2013-03-01 4 views
3

클래스 멤버를 선언하면 class Bar; Bar* m_bar 또는 더 짧게 class Bar* m_bar 중 하나를 사용할 수 있습니다. 그러나 이름 해석은 다르게 행동하는 것 같습니다.전달 선언 구문의 동작이 다릅니다.

예를 들어이 완벽하게 컴파일 :

struct Foo { 
    Foo(); 
    struct Bar; 
    Bar* m_bar; 
    struct Bar { 
     int m_baz; 
    }; 
}; 

Foo::Foo(){ 
    m_bar = new Foo::Bar; 
} 

이되지 않지만, 컴파일러는 m_bar의 유형 Foo::Bar 것이 아니라 단지 Bar 생각하기 때문에 :

내 질문이 더 밖으로
struct Foo { 
    Foo(); 
    struct Bar* m_bar; 
    struct Bar { 
     int m_baz; 
    }; 
}; 

Foo::Foo(){ 
    m_bar = new Foo::Bar; 
} 

호기심이 실제 문제 (그리고 나는 C++에서 순방향 선언과 중첩 클래스는 다루기 힘든 주제라는 것을 알고있다.)하지만 컴파일러는 왜 두 번째 버전을 전역 이름으로 해석 하는가?

+0

'struct Bar * m_bar;'는 * 클래스 정의 *에'struct bar '를 추가하지 않는다는 사실을 알고 있습니다. 단지 "바 (Bar)"라는 주변 클래스가 있습니다. " 첫 번째 버전은 먼저 중첩 된 클래스 선언을'Foo' 클래스 정의에 추가 한 다음'Bar *'는 * that * 중첩 클래스를 참조합니다. –

답변

2

spec은 3.3.2p6bullet2에서 이것을 말합니다. 실제로는 선언 된 이름이 어떤 범위에 추가되는지 말합니다. 올바르게 기억하면 클래스가 해당 네임 스페이스의 멤버라는 명시적인 규칙이 없습니다.

저는 이것이 C 호환성의 중요한 특징이라고 생각합니다. 이 방법이 아니라면 클래스는 C에서는 전역이지만 C++에서는 클래스 멤버가됩니다.

+0

표준을 가르쳐 주셔서 고마워요 :). 올바르게 이해하면 struct bar * m_bar'를 선언 할 때 "식별자가 선언을 포함하고있는 가장 작은 클래스가 아닌 함수 프로토 타입 범위에서 선언됩니다." (3.3.1.5)이므로 명시 적으로 모든 클래스 범위 밖에 있습니다. – Louen

관련 문제