宣佈對象我具有低於一個簡單的代碼:問題的在C++
class B;
class A{
B b;
};
class B{
public:
B(){
}
};
在A類的定義,我有一個B-類型屬性。使用MS Visual Studio來編譯,我有以下錯誤:
error C2079: 'A::b' uses undefined class 'B'
由於某些原因,我不能把以前的A類的一個B級的定義。任何想法?
宣佈對象我具有低於一個簡單的代碼:問題的在C++
class B;
class A{
B b;
};
class B{
public:
B(){
}
};
在A類的定義,我有一個B-類型屬性。使用MS Visual Studio來編譯,我有以下錯誤:
error C2079: 'A::b' uses undefined class 'B'
由於某些原因,我不能把以前的A類的一個B級的定義。任何想法?
編譯器已經告訴你什麼是錯誤的:A有一個未定義類型的成員數據b。您的正向聲明:
class B;
就是這樣:一個聲明,而不是一個定義。由於類A直接包含B的實例(不僅僅是指向B的指針),因此編譯器需要知道B的確切大小:它需要它的定義,而不僅僅是一個聲明,即在某個時刻B會存在的承諾。
在這裏做最簡單的事情是重新安排事情是這樣的:
class B{
public:
B(){
}
};
class A{
B b;
};
編輯:又見this question的聲明和定義的區別。
進一步編輯:另一種方法是將您的成員數據更改爲指針或引用。 請注意,這不是一個簡單的語法變化:它對您的對象的生命週期有影響,因爲A :: b指向的對象可以在A的銷燬後繼續存在。
如果您想要的是組成(B是A的一部分,並與A一起死亡),使用指針會使你的生活變得更加困難,收益甚微。
更多編輯(!):剛纔意識到我誤解了你的問題的結尾;有什麼理由阻止你在A之前宣佈B?
如果他們不能解決,你可能不得不去指針路線。這些原因可能是您的物體耦合過於緊密的標誌! (也許B需要成爲A的內部類,或者簡單地合併成單個對象?)
感謝您的詳細解答!:) – anhldbk 2011-03-19 03:58:13
class A;
class B {
A * getA();
};
class A {
B b;
};
這是解決這個問題的典型方法。你必須有B的定義,以便有一個B b;
成員。
你需要預先聲明,以聲明引用/指針B,你需要爲了做任何其他與B中的完整定義(如定義變量,調用一個成員函數等)
OPs代碼中沒有循環依賴關係 – 2011-03-18 10:29:19
@Space:不在他的示例中 - 雖然解釋仍然正確 – Erik 2011-03-18 10:42:34
如果將引用更改爲指向B
的指針b
,則可以執行此操作。
class A{
B* bPtr;
};
class B{
public:
B(){
}
};
原則上,你並不需要一個顯式聲明 - 也就是說,一個向前聲明是所有需要 - 當你不需要類的實際大小,或訪問到類中的類型和成員函數。
在您的原始示例中,您正在對B
進行直接引用。因此,編譯器需要知道關於B
的所有內容,因此需要顯式聲明而不是前向聲明。
通過使用A
類聲明使用指向B
的指針,那麼您可以使用前向聲明離開。
編輯
有些鏈接可能解釋的理念爲您:
http://www-subatech.in2p3.fr/~photons/subatech/soft/carnac/CPP-INC-1.shtml
http://www.codeguru.com/forum/showthread.php?t=358333(見職位#2)
C++有一個「不完整」類的概念,它是你需要知道的。
使用不完整的類可以讓你在許多情況下只使用一個類,知道它是一個類,而不知道它是什麼。
這使得類詳細信息可以稍後更改,而不需要重新編譯,因此它是耦合模型中較弱的依賴關係。
你需要一個完整的類:
你只需要一個不完整的類:
我想你只需要一個完整的類來聲明返回一個函數,並可能宣佈一個函數,一個作爲參數,但在當時定義或調用它需要的是完整的功能即使你不使用返回值。
你是什麼意思,說「有些原因」?這些原因是什麼? – 2011-03-18 10:22:40
如果B類不需要定義類A - 先定義類B,然後定義A類。否則,你將被迫使用指針。 – rmflow 2011-03-18 10:27:15
這裏的原因可以用「循環依賴」來解釋。請參閱http://en.wikipedia.org/wiki/Circular_dependency。所有我想要的是將2個類的聲明放在一個文件中。 :( – anhldbk 2011-03-19 03:50:46