2013-03-07 33 views
0

儘管有許多類似這樣的問題,我無法找到一個能夠回答這樣一個簡單查詢的問題 - 但是由於體積太大,如果我錯過了它,你將不得不原諒我。轉發聲明不修復不完整類型

在下面的代碼時,將產生以下錯誤(用G ++):'error: field 'CompoundField' has incomplete type'

class SimpleClass; 
class CompoundClass; 

class CompoundClass{ 
    public: 
    SimpleClass CompoundField; 
}; 

class SimpleClass{ 
    public: 
    unsigned int SimpleField; 
}; 

int main(){ 
    CompoundClass obj; 
    obj.CompoundField.SimpleField=5; 
    return 0; 
} 

這是爲什麼當這兩個類被前置聲明?一個直接的解決方案是將CompoundClass移動到SimpleClass之後,或者將CompoundField指向SimpleClass,但這並不能解釋此處的根本問題。

爲了更準確,其他的答案表明這是由於不知道孩子的大小的編譯器(即SimpleClass),這是爲什麼當SimpleClass規模可能相對容易地發現了什麼?

+1

定義「相對容易」。 C++仍然具有編寫單通編譯器的理論能力。等到'SimpleClass'被定義在後面時,將需要潛在的無限的前瞻。考慮如果用戶在'main'後面定義'SimpleClass'的含義。 – mythagel 2013-03-07 02:47:42

+0

@mythagel定義「單次傳球」。例如,在一個'class {}'範圍內的定義首先被解析爲聲明,然後再次解析所有的類成員聲明。這裏的問題是子對象的類型層次必須是非循環的,否則你會得到無限大小的對象。形成有向無環圖的類型可以在沒有前向聲明的情況下定義,這是此處的解決方案。前向聲明和不完整類型僅用於定義引用(包括指針和智能指針)。 – Potatoswatter 2013-03-07 03:21:28

+0

@Patatoswatter非常好的一點,也許我應該說有界限的前瞻性。我試圖解決實際問題,因爲R4D4似乎已經知道在接受的答案中提出的解決方案。 – mythagel 2013-03-07 03:24:17

回答

3

編譯器看到這個

class SimpleClass; 
class CompoundClass; 

class CompoundClass{ 
    public: 
    SimpleClass CompoundField; 
}; 

它需要找出一個CompoundClass需要的內存(沒有一點頭緒約SimpleClass內存要求)。

因爲它不知道有多少個整數,字符串等。爲了騰出空間 - 它拋出了它的手。

但是,如果你沒有

class SimpleClass; 
class CompoundClass; 

class CompoundClass{ 
    public: 
    SimpleClass *CompoundField; 
}; 

然後,它會知道 - 只需要一個指針(void *將能滿足所有不測事件!)

相關問題