一、問題描述
現在有兩個類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 #include "B.h"//A的頭文件導入了B的頭文件 //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 //#include "A.h"//B的頭文件沒有導入A的頭文件,需要有三個地方需要注意! extern class A;//注意1:需要用extern聲明A class B { private: int b; A* objecta;//注意2:調用A的時候需要用指針 public: B(); int getb(); void handle(); }; #endif _B
A的定義文件A.cpp:
#include#include "A.h" using namespace std; A::A() { this->a=100; } int A::geta() { return a; } void A::handle() { cout<<"in A , objectb.b="<
B的定義文件B.cpp:
#include#include "B.h" #include "A.h"//注意3:在B.cpp裡面導入A的頭文件 using namespace std; B::B() { this->b=200; } int B::getb() { return b; } void B::handle() { objecta=new A(); cout<<"in B , objecta->a="< geta()<
main.cpp:
#include#include #include "A.h" //#include "B.h" //因為A.h裡面已經包含B.h,所以在此不需要導入B.h了。 using namespace std; void main() { A a; a.handle(); B b; b.handle(); system("pause"); }
運行結果:
四、注意
下面情況編譯不能通過:
A.h中包含B.h且B.h中包含A.h