一、问题描述
现在有两个类A和B需要定义,定义A的时候需要用到B,定义B的时候需要用到A。
二、分析
A和B的定义和调用都放在一个文件中肯定是不可以的,这样就会造成两个循环调用的死循环。
根本原因是:定义A的时候,A的里面有B,所以就需要去查看B的占空间大小,但是查看的时候又发现需要知道A的占空间大小,造成死循环。
解决方法:
(1)写两个头文件A.h和B.h分别用于声明类A和B;
(2)写两个.cpp文件分别用于定义类A和B;
(3)在A的头文件中导入B的头文件;
(4)在B的头文件中不导入A的头文件,但是用extern 的方式声明类A,并且,在B中使用A的时候要用指针的形式。
原理:在B中用指针调用A,那么在A需要知道B占空间大小的时候,就会去找到B的定义文件,虽然B的定义文件中并没有导入A的头文件,不知道A的占空间大小,但是由于在B中调用A的时候用的指针形式,B只知道指针占4个字节就可以,不需要知道A真正占空间大小,也就是说,A也是知道B的占空间大小的。
三、C++示例A的头文件A.h:
#ifndef _A
#define _A
<strong>#include "B.h"//A的头文件导入了B的头文件</strong>
//extern class B;
class A
{
private:
int a;
B objectb;//A的头文件导入了B的头文件,在调用B的时候就可以不用指针
public:
A();
int geta();
void handle();
};
#endif _A
B的头文件B.h:
#ifndef _B
#define _B
<strong>//#include "A.h"//B的头文件没有导入A的头文件,需要有三个地方需要注意!
extern class A;//注意1:需要用extern声明A</strong>
class B
{
private:
int b;
A* objecta;//注意2:调用A的时候需要用指针
public:
B();
int getb();
void handle();
};
#endif _B
A的定义文件A.cpp:
#include <iostream>
<strong>#include "A.h"</strong>
using namespace std;
A::A()
{
this->a=100;
}
int A::geta()
{
return a;
}
void A::handle()
{
cout<<"in A , objectb.b="<<objectb.getb()<<endl;
}
B的定义文件B.cpp:
#include <iostream>
<strong>#include "B.h"
#include "A.h"//注意3:在B.cpp里面导入A的头文件</strong>
using namespace std;
B::B()
{
this->b=200;
}
int B::getb()
{
return b;
}
void B::handle()
{
objecta=new A();
cout<<"in B , objecta->a="<<objecta->geta()<<endl;
}
main.cpp:
#include <iostream>
#include <cstdlib>
<strong>#include "A.h"
//#include "B.h" //因为A.h里面已经包含B.h,所以在此不需要导入B.h了。</strong>
using namespace std;
void main()
{
A a;
a.handle();
B b;
b.handle();
system("pause");
}
运行结果:
四、注意
下面情况编译不能通过:
A.h中包含B.h且B.h中包含A.h