您創建了一個圓形夾雜:你包括D1.h
爲D2.h
,你還包括D2.h
爲D1.h
。循環包容從未起作用,從未達到任何目的。
你的循環包含是類定義之間循環依賴的直接後果。在你的代碼中,這兩個類的定義都是相互引用的,要求這兩個類的類型都是完整的(要完全定義)。這意味着無論你做什麼,你的代碼都是無法編譯的。您需要打破類定義之間的循環依賴關係。
在你的情況下,可以通過以下方式來完成。
保持D1.h
不變,即將D2.h
保持爲D1.h
,並保持類D1
的定義原樣。
然而,不包括D1.h
到D2.h
而是引入D1
預先聲明爲D2.h
class D1;
變化D2
的定義
class D2: public B {
public:
int get(D1& d);
};
注意:不要試圖去定義方法get
正確定義類D2
。你必須搬遷的D2::get
定義一些其他的地方,那裏的D1
完整定義也是可見的(就像D2.cpp
例如,其中應包括D1.h
和D2.h
)
int D2::get(D1& d)
{
return d.a;
}
就是這樣。通過這種方式定義D2::get
的副作用是它變爲非內聯。如果你真的想保持它內聯,你必須把它定義爲
inline int D2::get(D1& d)
{
return d.a;
}
,並確保它是某種只包括後的D1
完整定義。例如,您可以將它放在第三個頭文件(D2_aux.h
或類似的東西)中,並記住在之後包括它D1.h
。
當然,嘗試解決此問題的更好方法是重新考慮整個設計。你真的需要D1
內的朋友聲明嗎?也許你應該以某種方式重新設計你的代碼,以消除這個朋友聲明的需要,從而消除這種依賴性。
或者,您也可以通過改變D1.h
並保持D2.h
不變解決。然而,跟着你將有一個更徹底的和寬鬆的
friend class D2;
,以取代「細粒度」 friend聲明
friend int D2::get(D1&);
和D1.h
去除D2.h
列入該路徑。
前朋友聲明要求類D2
是完整的,這實際上是創建「不可破壞」的依賴關係。後面的聲明不需要D2
是完整的。
來源
2012-08-16 16:11:10
AnT
感謝man ...'get()'的定義其實是最初的問題(但是不知道,那麼我在這兩個類中都包含了.h文件)。從來沒有想到這一點。 – scarably 2012-08-16 16:20:54
不,實際上......我可以通過在D2內部創建'int get_d1(){return a}'和'int get(D1&x)'{{return x.get_d1();}'來重新設計代碼。 。但我認爲第一個版本更好? – scarably 2012-08-16 16:36:08
stefaneli31:是的,這就是我所說的「重新思考設計」和「不需要朋友聲明」。 – AnT 2012-08-16 16:42:36