2013-02-05 4 views
0

저는 C++의 초보자이며 한 번에 두 개 이상의 네임 스페이스를 처리하는 방법을 이해하는 데 어려움을 겪고 있습니다. 내 MVC 응용 프로그램에서 컨트롤러는 동작을 전달하기 위해 컨트롤러에 대한 참조가 필요하고 컨트롤러는 일부를 표시하기 위해 뷰에 대한 참조가 필요합니다.C++ 네임 스페이스/식별자 문제

나는 거의 모든 것을 내 응용 프로그램에서 제거했으며, 아직 nomespace 및 선언되지 않은 식별자에 대한 많은 컴파일 오류가 있습니다. 이것은 제거 코드 :

#ifndef _geometria 
#define _geometria 

namespace core_stuff { 

/*this namespace contains Model and Controller */ 

class Model { 

public: 
    Model(); 
    //void doSomething(); 

}; 

class Controller { 

public: 
    Controller(); 
    void setView(ui_stuff::View v); 

}; 

} 

namespace ui_stuff { 

/*this namespace contains View and other UI classes libraries, not included here because I am semplifying the whole stuff */ 

class View { 

public: 
    View(); 
    void setController(core::Controller c); 

}; 

} 


#endif 

이는 구현입니다 :

#include "geometria.h" 
#include <iostream> 


//implementation of core_stuff namespace 

core_stuff::Model::Model() { } 

core_stuff::Controller::Controller() { } 

void core_stuff::Controller::setView(ui_stuff::View v) { 
//do some kind of operation in my view 
} 


//implementation of ui_stuff namespace*/ 

ui_stuff::View::View() { /* */ } 

void ui_stuff::View::setController(core_stuff::Controller c) { 
//do some kind of operation on the controller 
} 



/* main */ 
int main (int nArgs, char* args[]) { 
core_stuff::Model m; 
core_stuff::Controller c; 
ui_stuff::View v; 
v.setController(c); 
c.setView(v); 
} 

컴파일 오류의 아주 긴 목록의 첫 번째는 헤더 파일에

void setView(ui_stuff::View v); 

라인을 포함한다 , ui_stuff 네임 스페이스에 액세스 할 수 없습니다.

줄 (20) : 오류 C2653 : 'ui_stuff'는 ac의 이름이 아닙니다. lass 또는 네임 스페이스

어떻게 해결해야합니까?

+2

네임 스페이스'core_stuff' 전에 네임 스페이스'ui_stuff'을 이동하십시오. –

+0

Aloks 주석에 대해 자세히 설명하기 위해 C++가 순서대로 파싱됩니다. 그것은 전체 파일을 읽지 않고 형식을 알아 내려고 시도합니다. 순서대로 있어야합니다. – dutt

+0

당신이 함수를 할 수있는 것처럼 네임 스페이스를 정의한 다음 선언하면 순서에 대해 걱정할 필요가 없습니까? – TopGunCoder

답변

3

당신은 나 또한 참조로 전달했습니다

namespace ui_stuff 
{ 
    class View; // a forward declaration of ui_stuff::View 
} 

namespace core_stuff 
{ 
    class Controller { 
     void setView(ui_stuff::View& v); 
    }; 
} 

namespace ui_stuff 
{ 
    class View 
    { 
    public: 
     void setController(core_stuff::Controller& c); 
    }; 
} 

를 사용하기 전에 ui_stuff::View에 대한 기대 선언을해야합니다. 그게 아마도 당신이 원하는 것일 겁니다 (보기의 복사본이 아닙니다).

나는 당신의 선언을 변경하는 이유에 대한 간단한 설명

: 당신이 Controller 하는 방법에 값에 의해 View을 통과 할 수는 View 가치에 의해 Controller을 전달합니다. 이는 값으로 전달할 때 전달하는 전체 객체를 정의해야하기 때문입니다. 제어기가보기의 완전한 정의에 의존하기 때문에보기 전에 제어기를 완전히 정의 할 수 없습니다. 그러나 같은 이유로 컨트롤러 앞에보기를 정의 할 수 없기 때문에 "참조로 전달"비트를 사용합니다.

두 클래스가 선언되면 서로 상호 작용하는 방식을 정의 할 수 있습니다.

+0

이것이 내가 찾고있는 것이라고 생각합니다. – alessiop86

1

dutt saide로 C++가 순서대로 파싱됩니다. 즉, C++ 코드의 각 행에서 컴파일러는 지금까지 정의 된 내용 만 알고 있습니다.

문제를 해결하려면 ui_stuff를 핵심 요소보다 먼저 이동해야하지만 클래스 스텁도 살펴 봐야합니다. 예 :

namespace ui_stuff { 
class View; //This class exists but I will not define it yet. 
} 

문제는 당신이보기 정확히 알 수 없기 때문에 당신이 하지, 복사 등의보기를 전달할 수 있다는 것입니다. 그러나 포인터 또는 참조으로 전달할 수 없습니다. 포인터가 둘 다 참조가 데이터 크기를 알아야하기 때문에 전달할 수 없습니다.

그래서, 대신이 일을 코드에서 :

class Controller { 

public: 
    Controller(); 
    void setView(ui_stuff::View v); 

}; 

당신은이 작업을 수행 할 것입니다 :

class Controller { 

public: 
    Controller(); 
    void setView(ui_stuff::View& v); 

}; 

& 당신이 이미 존재하는 뷰의 참조를 기대하고 있음을 나타냅니다, 새로운 사본 대신에.

+0

다른 주석에서 말했듯이 순서를 뒤집을 수 없거나 반대되는 문제가 있습니다. View의 setController 메서드는 Controller 클래스와 ui_core 네임 스페이스를 찾지 않습니다. – alessiop86

+0

그래서 클래스 스텁을 사용해야합니다. 참조 점 (일명 &)을 얻었습니까? 필요한 경우 좀 더 자세히 설명 할 수 있습니다. –