在構造自己的類時,有可能會碰到兩個類之間的相互引用問題,例如:定義了類A類B,A中使用了B定義的類型,B中也使用了A定義的類型
例如:
Cup.h
#ifndef CUP_H #define CUP_H #include "Box.h" class Cup { public: ~Cup(); Box b; Cup(); }; #endif // CUP_H
Cup.cpp
#include "Cup.h" #include <iostream> using namespace std; Cup::Cup() { cout << "Cup cons" << endl; } Cup::~Cup() { cout << "Cup des" << endl; }
Box.h
#ifndef BOX_H #define BOX_H #include "Cup.h" class Box { public: Box(); ~Box(); Cup cup; }; #endif // BOX_H
Box.cpp
#include "Box.h" #include <iostream> using namespace std; Box::Box() { cout << "Box cons" << endl; } Box::~Box() { cout << "Box des" << endl; }
在這種情況下,想想可以有b.cup.b.cup.b.....…………,這種定義方式類同程序中的死循環。編譯器肯定會報錯的。
我的報錯信息是
include\Cup.h|10|error: 'Box' does not name a type|
所以,一般來說,兩者的定義,至少有一方是使用指針,或者兩者都使用指針,但是決不能兩者都定義實體對象。
言歸正傳,那么,在定義時因為相互引用肯定會需要相互包含頭文件,如果僅僅只是在各自的頭文件中包含對方的頭文件,是通不過編譯的,如上面的情況所示
解決的辦法,讓其中一個(例如Cup)只聲明對方(class Box;)並且使用指針(Box *b),並且不包含頭文件Box.h,在實現文件(Cup.cpp)文件中再包含Box.h,修改后的代碼如下:
Cup.h
#ifndef CUP_H #define CUP_H class Box; class Cup { public: void createBox(); ~Cup(); Box *b; Cup(); }; #endif // CUP_H
Cup.cpp
#include "Cup.h" #include <iostream> #include "Box.h" using namespace std; Cup::Cup(): b(NULL) { cout << "Cup cons" << endl; } Cup::~Cup() { if (b!=NULL) delete b; cout << "Cup des" << endl; } void Cup::createBox() { b = new Box(); }
注意為什么不在Cup::Cup()中直接b = new Box(),因為這是死循環,直接StackOverflow,所以使用了createBox()
最后再寫一個main.cpp來測試,可以去嘗試解釋一下運行結果
#include "Box.h" #include "Cup.h" #include <iostream> using namespace std; int main() { Box b; cout << "something in the middle" << endl; Cup c; c.createBox(); }
