2011-09-25 115 views
0

我無法使用MinGW C++將涉及嵌套類的對象模型放在一起。下面是我的公開問題的示例:爲什麼我無法從外部定義嵌套類?

了foo.h:

/* 
* foo.h 
* 
* Created on: Sep 25, 2011 
*  Author: AutoBot 
*/ 

#ifndef FOO_H_ 
#define FOO_H_ 

class Foo 
{ 
public: 
    class Bar; 
    Bar bar; 
} extern foo; 


#endif /* FOO_H_ */ 

bar.h:

/* 
* bar.h 
* 
* Created on: Sep 25, 2011 
*  Author: AutoBot 
*/ 

#ifndef BAR_H_ 
#define BAR_H_ 

#include <iostream> 
using namespace std; 

#include "foo.h" 

class Foo::Bar 
{ 
public: 
    void Test() {cout <<"Test!";} 
}; 


#endif /* BAR_H_ */ 

main.cpp中:

/* 
* main.cpp 
* 
* Created on: Sep 25, 2011 
*  Author: AutoBot 
*/ 



#include "foo.h" 

Foo foo; 

int main (int argc, char *argv[]) 
{ 
    foo.bar.Test(); 
    return 0; 
} 

Eclipse CDT的構建日誌:

**** Build of configuration Debug for project NestedClassTest **** 

**** Internal Builder is used for build    **** 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\main.o ..\src\main.cpp 
In file included from ..\src\main.cpp:10:0: 
..\src\/foo.h:15:6: error: field 'bar' has incomplete type 
..\src\main.cpp: In function 'int main(int, char**)': 
..\src\main.cpp:16:6: error: 'class Foo' has no member named 'bar' 
Build error occurred, build is stopped 
Time consumed: 171 ms. 

所以基本上它不能識別bar.h中bar的定義。這是正常的嗎?爲什麼我不能以這種方式定義嵌套類?這只是MinGW工具鏈的限制嗎?任何幫助/建議表示讚賞。注意:在我的實際程序中,我打算將它的「foo」作爲理論上的singleton類。它將代表應用程序作爲一個整體,並且它的子系統(或「酒吧」)將在類中定義和實例化。我這樣做是爲了讓代碼更易於管理。如果有人有一個更可行的設計模式,請告訴我!

+0

爲什麼你需要一個代表應用程序的對象?該應用程序由_running_這個事實來表示。如果代碼可以執行,那麼你就在應用程序中。我可以理解使用單例提供對某些特定數據(例如文件系統)的訪問權限,但使用單例表示應用程序沒有多大意義。 –

+0

是的,也許我太過分了。我希望單身人員確實管理的一件事是所有子系統的啓動/關閉和服務(通過'start','end'和'update'函數)。這讓我傾向於把所有實際的子系統都放在裏面,但是我可能不應該這樣做,因爲限制代碼的使用。 – AutoBotAM

回答

2

的問題是在這裏:

class Foo 
{ 
public: 
    class Bar; 
    Bar bar; 
}; 

此時Foo::Bar是一個不完整的類型。而且你不能聲明一個不完整類型的變量。這與試圖做到這一點沒什麼兩樣:

class Foo; 
Foo foo; 

他們都是不允許的,出於同樣的原因。

您可以將bar轉換成某種(智能)指針。但這是解決這個問題的唯一方法。

+0

「沒有必要讓它成爲一個嵌套類」......當然,所有'Foo :: Bar'的成員都可以訪問'Foo'的私有成員。 –

+0

Ben Voigt說,事實上,這是我試圖維持這種模式的一個關鍵原因。基本上我希望我的所有子系統都能夠在單身人員課程中進行交互(在op中閱讀我的備註)。也許我可以找到一種方法來使用朋友類並從那裏建立起來。 – AutoBotAM

+0

實際上,朋友類不會削減它,因爲我仍然必須將foo的成員指定爲「foo.bar1」,「foo.bar2」等等(而不僅僅是「bar1」和「bar2」)。我用Nicol Bolas的指針想法,經過一些調整後,它似乎工作。如果指針不會給我帶來太多麻煩,我會繼續追求這個對象模型。我明白,在當時的酒吧評估,它是不完整的,但我認爲這是不幸的,我必須訴諸指針,因爲這一點。無論哪種方式它現在的作品。謝謝! – AutoBotAM

2

一個你這裏的問題是,當你做:

class Foo 
{ 
public: 
    class Bar; 
    Bar bar; 
} extern foo;

Bar bar是非法的,因爲你要使用它提供了一個不完整的類型class bar;

您還沒有包括Bar.h

+0

如果我將'Bar bar'改爲'Bar * bar'(foo.h),添加'#include「foo.h」'(bar.h),並將'foo.bar.Test()'改爲'foo .bar-> Test()'(main.cpp),我得到兩個錯誤:'.. \ src \ /bar.h:16:7:錯誤:'Foo'還沒有被聲明爲'和'.. \ src \/bar.h:17:1:錯誤:期望'{'token'之前的非限定id因此,它看起來像條已經正確初始化,但現在酒吧看不到Foo!xD – AutoBotAM

+0

這隻有在你在main.cpp中包含bar.h並從bar.h中刪除include foo.h的情況下才有效。 – Rutix

+0

好的,我已經完成了,現在看起來可行!如果指針不會造成太大麻煩,我會繼續追求這個對象模型。謝謝! – AutoBotAM

相關問題