C++两个类相互引用的问题

本文探讨了C++中两个类相互引用导致的编译错误问题,并提供了解决方案——前置声明。通过示例代码展示了如何正确使用前置声明来避免相互依赖导致的编译失败。

c++中常会出现两个类相互引用的问题,如果直接相互引用对方的头文件,编译时会报错,下面给出一个例子

A.h

#ifndef _A_H
#define _A_H
#include "B.h"

class A
{
public:
    B b;
    int ia;
};

#endif 

B.h

#ifndef _B_H
#define _B_H

#include "A.h"

class B
{
public:
    A a;
    int ib;
};

#endif 

main.cpp

#include "A.h"
#include "B.h"

int main(int argc, char const *argv[])
{
    A a;
    B b;
    return 0;
}

编译报错

# wenxiaole at wenxiaoledeMacBook-Pro.local in ~/test [12:33:59]
$ g++ main.cpp
In file included from main.cpp:1:
In file included from ./A.h:3:
./B.h:9:5: error: unknown type name 'A'
    A a;
    ^
1 error generated.

由于编译顺序的问题,提示类型A未声明。例如:在编译A.h时发现包含了B.h,然后去编译B.h, 发现又引用了A.h,之后就会编译报错。

解决该问题的方法是前置声明。
比如我要盖一个屋子(CHOuse),光有屋子还不行啊,我还得有床(CBed)。但是屋子还没盖好,总不能先买床吧,床的大小我定了,改天买。先得把房子盖好,盖房子的时候我先给床留个位置,等房子盖好了,我再决定买什么样的床。前置声明就是我在声明一个类(CHouse)的时候,用到了另外一个类的定义(CBed),但是CBed还没有定义呢,而且我还先不需要CBed的定义,只要知道CBed是一个类就够了。那好,我就先声明类CBed,告诉编译器CBed是一个类(不用包含CBed的头文件):然后在CHouse中用到CBed的,都用CBed的指针类型代(因为指针类型固定大小的,但是CBed的大小只用知道了CBed定义才能确定)。等到要实现CHouse定义的时候,就必须要知道CBed的定义了,那是再包好CBed的头文件就行了。

代码示例如下:

A.h

#ifndef _A_H
#define _A_H

class B;//前置声明,此时不包含B的头文件,否则会重复定义,直到在A.cpp文件中实现的时候再包含B的头文件。
class A
{
public:
    B* b;
    void setB();
    ~A();
};

#endif 

B.h

#ifndef _B_H
#define _B_H
#include "stdio.h"
#include "A.h"   

class B
{
public:
    A a;
    void dosomething()
    {
        printf("dosomethingA\n");
    }
};

#endif 

A.cpp

#include "A.h"
#include "B.h"  //实现时再包含B的头文件

A::~A()
{
    delete b;
}

void A::setB()
{
    b->dosomething();
}

main.cpp

#include "A.h"
#include "B.h"

int main(int argc, char const *argv[])
{
    A a;
    B b;
    return 0;
}

编译通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值