2011-09-25 3 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; 
} 

이클립스 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"를 의도합니다. 응용 프로그램을 전체적으로 나타내며 하위 시스템 (또는 "바")은 클래스 내부에서 한 번 정의되고 인스턴스화됩니다. 나는 코드를 좀더 다루기 쉽도록하려고 노력하고있다. 누군가가 더 실현 가능한 디자인 패턴을 염두에두고 있다면 말해주세요! 당신이 불완전한 유형을 제공 class bar;를 사용하려고하기 때문에

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

Bar bar 불법 : 여기가 문제의

+0

왜 응용 프로그램을 나타내는 개체가 필요합니까? 응용 프로그램은 _running_이라는 사실로 표시됩니다. 코드를 실행할 수 있으면 응용 프로그램에 있습니다. 특정 특정 데이터 (예 : 파일 시스템)에 대한 액세스를 제공하기 위해 싱글 톤을 사용하는 것을 이해할 수 있지만 응용 프로그램을 나타내는 싱글 톤을 갖는 것은별로 의미가 없습니다. –

+0

그래, 아마도 나는 한 클래스에 너무 많은 것을 넣을거야. 싱글 톤이 확실하게 관리되기를 원하는 한가지는 모든 서브 시스템의 시작/종료 및 서비스 ('start','end' 및'update' 함수를 통해)입니다. 이것은 내게 실제 서브 시스템을 모두 넣는 경향이 있었지만, 코드 사용이 제한되어 있으므로 그렇게해서는 안됩니다. – AutoBotAM

답변

2

문제가 포함되어 있지 않습니다

은 여기에 있습니다 :이 시점 Foo::Bar에서

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

이 불완전한 유형입니다. 그리고 불완전한 타입의 변수를 선언 할 수 없습니다. 이 작업을 시도하는 것과 다를 바가 없습니다.

class Foo; 
Foo foo; 

이들은 모두 허용되지 않으며 동일한 이유로 사용됩니다.

bar을 (스마트) 포인터로 사용할 수 있습니다. 그러나 이것이 그 문제를 해결할 수있는 유일한 방법입니다.

+0

"중첩 된 클래스를 만드는 것이 중요하지 않습니다."... 물론 Foo :: Bar의 모든 멤버는 Foo의 private 멤버에 액세스 할 수 있습니다. –

+0

벤 보이트 (Ben Voigt)가 말한 것은 사실, 이것이 내가이 모델을 유지하려고하는 주요 이유입니다. 기본적으로 나는 모든 서브 시스템을 싱글 톤 클래스 내에 존재하면서 서로 상호 작용할 수 있기를 바란다. 어쩌면 친구 클래스를 사용하여 거기에서 빌드하는 방법을 찾을 수 있습니다. – AutoBotAM

+0

사실 foo의 멤버를'foo.bar1','foo.bar2' 등과 같이 ('bar1'과'bar2' 대신에) 지정해야하기 때문에 친구 클래스는 그것을 잘라 내지 않을 것입니다. 나는 Nicol Bolas의 포인터 아이디어를 사용했고 약간의 조정 후에는 효과가있는 것으로 보인다. 포인터가 너무 많은 문제를주지 않으면이 객체 모델을 계속 추구 할 것입니다. 나는 바가 평가 될 때 그것이 불완전하다는 것을 이해한다. 그러나 나는 그것 때문에 포인터에 의지해야만한다는 것이 불행하다고 생각한다. 어느 쪽이든 그것은 지금 작동합니다. 감사! – AutoBotAM

2

하나는, 당신이 할 때이다. 또한 Bar.h

+0

'bar bar'를'bar * bar' (foo.h)로 변경하면'#include "foo.h"(bar.h)를 추가하고'foo.bar.Test()'를'foo '.. \ src \ /bar.h : 16 : 7 : 오류 :'Foo '가 선언되지 않았으며'.. \ src() \ /bar.h : 17 : 1 : 오류 : '{'token' 이전에 unqualified-id가 필요합니다.} 막대가 올바르게 초기화 된 것처럼 보이지만 이제 Bar는 Foo를 볼 수 없습니다!xD – AutoBotAM

+0

main.cpp에 bar.h를 포함하고 bar.h에서 include foo.h를 제거한 경우에만 작동합니다. – Rutix

+0

좋아, 내가 해봤는데 지금은 효과가있는 것 같다! 포인터가 너무 많은 문제를 일으키지 않으면이 객체 모델을 계속 추구 할 것입니다. 감사! – AutoBotAM

관련 문제