2010-04-08 4 views
32

중첩 클래스를 전달 선언 한 다음 외부 클래스의 데이터 멤버에 대한 구체적인 (포인터/참조가 아닌) 유형으로 사용할 수 있습니까?C++ 중첩 클래스/전달 선언 문제

I.E.

class Outer; 

class Outer::MaybeThisWay // Error: Outer is undefined 
{ 
}; 

class Outer 
{ 
MaybeThisWay x; 

class MaybeThatOtherWay; 

MaybeThatOtherWay y; // Error: MaybeThatOtherWay is undefined 
}; 
+0

귀하의 코드의 끝없는 사슬처럼 보인다 "외부 외부 외부 외부를 포함 포함 포함 ..." – Muxecoid

+0

[내부 클래스를 선언하는 방법은 무엇입니까?] (http://stackoverflow.com/questions/1021793/how-do-i-forward-declare-an-inner-class) –

답변

37

이와 같이 중첩 클래스를 forward-declare 할 수 없습니다.

당신이하려는 일에 따라 바깥 레이어의 클래스가 아닌 네임 스페이스를 사용할 수 있습니다. 당신은 이러한 클래스에게 아무런 문제가 앞으로-선언 할 수 없습니다 : 외부가 될하기 위해 외부 절대적으로 클래스이어야합니다

namespace Outer { 
    struct Inner; 
}; 

Outer::Inner* sweets; // Outer::Inner is incomplete so 
         // I can only make a pointer to it 

, 그리고 네임 스페이스로를 신발 경적 수 없습니다, 당신은해야합니다 전달할 컨텍스트에서 완전한 유형을 선언하십시오.

class Outer 
{ 
    class Inner; // Inner forward-declared 
}; // Outer is fully-defined now 

Outer yes; // Outer is complete, you can make instances of it 
Outer::Inner* fun; // Inner is incomplete, you can only make 
        // pointers/references to it 

class Outer::Inner 
{ 
}; // now Inner is fully-defined too 

Outer::Inner win; // Now I can make instances of Inner too 
1

아니, 무슨 일이 많은 세부 사항에 부족한 앞으로 내가 당신의 질문으로 볼 수 있습니다 뭔가를 (누락하지 않는 한, 여기에 이해가되지 않습니다 선언

class Outer { 
public: //or protected or private 
    class Inner { 
    }; 

private: 
    Inner foo; 
}; 

잘못)

클래스가 전달 선언 된 경우 앞으로 선언 된 유형의 객체에 대한 참조 또는 포인터 선언 만 선언 할 수 있습니다. 회원이나 기능에 액세스하는 것을 포함하여 다른 작업을 수행 할 수 없습니다.

+1

Inner is forwardly 그것이 거기에 완전히 정의되어 있다고 선언했다. – CashCow

+0

여기에서 섹션을 역전하면 어떻게 될까요? 아마도 public 섹션의 일부 함수는 private 변수를 사용하므로 선언해야하지만 Inner는 private이어야합니다. 이제 Inner가 개인 섹션에서 어떻게 보이게 할 수 있습니까? – Sohaib

1

클래스가 전방 선언되었지만 아직 전체 정의가없는 경우 컴파일러가 클래스의 크기를 알지 못하기 때문에 클래스에 대한 포인터 만 선언 할 수 있습니다. 필드 또는 메소드의 이름).

0

참조 및 포인터가 아닌 MaybeThatOtherWay 유형의 속성을 선언하는 경우 컴파일러는 외부 클래스의 크기를 결정하기 위해 클래스의 전체 정의를 알아야합니다. 따라서 중첩 클래스인지 여부에 관계없이 전달 선언과 그 종류의 필드 선언을 사용할 수 없습니다.

15

포함하는 클래스를 완전히 지정하지 않고 중첩 된 클래스를 전달할 방법이 없습니다. 이 내 이름 지정 규칙 Outer_Inner 같이 나를 위해 작동

class Outer_Inner 
{ 
}; 

class Outer 
{ 
public: 
    typedef Outer_Inner Inner; 
}; 

하지만이 작은 트릭은 좀 유효한 클래스 이름이 아닙니다 문제를 해결, 그래서 그것이 중첩 클래스를 의미하는 것이 분명하다.

class Outer::Inner; 

을하지만, 적어도 그것은 앞으로 선언 할 수 있습니다 :

당신은 여전히 ​​앞으로이 같은 중첩 된 클래스를 선언 할 수 없습니다 당신이 방법이 마음에 들지 않는다면

class Outer_Inner; 

Outer_Inner 당신이 당신의 취향에 더 잘 맞는 중첩 된 클래스를위한 명명 규칙을 채택 할 수있는 것처럼 보입니다. Outer__Inner, Outer_nested_Inner

+3

두 개의 밑줄을 사용하지 마십시오 - 두 개의 밑줄을 포함한 이름은 어떤 용도로든 구현에 예약되어 있습니다. http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797 – villintehaspam

+0

여기에 직면 한 것과 같은 문제입니까? http://stackoverflow.com/questions/20214740/nested-class-as-a-template-parameter-of-parent-class-in-c –

0

형식을 함수 매개 변수 또는 정적 변수로 사용하면 클라이언트 측에서 수행 할 수 있습니다.예를 들어, 외부에서 이벤트 알림을받을 수 있습니다 :

인터페이스 :

class Client { 
public: 
private: 
    static void gotIt(int event); 
    class Helper; 
}; 

구현 :

#include <outer.hpp> 

class Client::Helper { 
public: 
    static void fromOuter(Outer::Inner const& inner) 
    { 
     gotIt(inner.event()); 
    } 
};