2010-05-07 3 views
4

Visual C++ 2005에 문제가 있습니다. 동일한 이름이지만 내부 클래스가 다른 외부 클래스가 혼동 스러울 수 있습니다.Visual C++에서 같은 이름의 내부 클래스에 문제가 발생했습니다.

두 계층에 문제가 발생합니다. 각 계층에는 내부 클래스로 수신기 인터페이스가 있습니다. B는 A의 리스너이며 그 위의 세 번째 레이어에 자체 리스너를 가지고 있습니다 (표시되지 않음).

코드의 구조는 다음과 같습니다

class A 
{ 
public: 
    class Listener 
    { 
    public: 
     Listener(); 
     virtual ~Listener() = 0; 
    }; 
    // ... 
}; 

에게 BH

class B : public A::Listener 
{ 
    class Listener 
    { 
    public: 
     Listener(); 
     virtual ~Listener() = 0; 
    }; 
    // ... 
}; 

: 리스너()과를 :: ~ 리스너는()에 정의되어 있습니다 A.cpp.

B.cpp는

B::Listener::Listener() {} 
B::Listener::~Listener() {} 

나는 오류를 얻을

B.cpp(49) : error C2509: '{ctor}' : member function not declared in 'B' 
르네사스 SH2A의 C++ 컴파일러는이 아무 문제가 없습니다 만, 그때는 다른 측면에서 Visual C++에서보다 더 진보적이다

, 너무.

리스너 인터페이스의 이름을 다른 이름으로 바꾸면 문제가 없어지지만 A 또는 B 대신 실제 클래스 이름이 다소 길어지는 것을 피하고 싶습니다.

내가 옳은 것은 C++입니까, 아니면 Visual C++의 불만 사항입니까?

리스너 인터페이스의 이름을 바꾸지 않고이 문제를 해결할 수있는 방법이 있습니까?

+0

'{ctor}'는 무엇인가요? B :: Listener :: Listener()입니까? 선언 및 정의와 일치하지 않는 헤더 또는 구현 파일에 오타가 없습니까? 또한 클래스 선언 다음에 세미콜론이 있다고 가정합니다. A :: ~ Listener()가 정의되고 A :: Listener는 public입니다. 이 코드는 OS X 10.5.8에서 g ++ 4.0.1에서 컴파일 된 코드가 고정되어 있다고 말할 수 있습니다. – wilhelmtell

+0

starblue, 문제를 실제로 재현하기 위해 문제를 해결했습니다. 다음에 직접하십시오. –

+0

고마워, 나는 또한'B'에 빠진'public'을 추가했다. – starblue

답변

1

게시 한 코드가 내 컴퓨터에서 설명한 것과 동일한 컴파일러 오류를 생성했습니다. 나 자신이 그 문제가 정확히 무엇인지 확신 할 수는 없지만, 순수한 가상 클래스를 상속하고 자손 내에서 순수 가상 클래스를 선언하는 것은 좋은 생각이 아닐 수도있다.

내가 수정 된 버전을 컴파일 관리, 어쩌면 이것은 당신이 당신의 문제를 해결하는 데 도움이 :

class OuterA 
{ 
    public: 
    class Listener 
    { 
     public: 
     Listener() {} 
     virtual ~Listener() = 0 {} 
    }; 

    OuterA() {} 
    ~OuterA(){} 
}; 

class OuterB : public OuterA::Listener 
{ 
    public: 
    class Listener 
    { 
     public: 
     Listener() {} 
     ~Listener() {} 
    }; 

    OuterB() {} 
    ~OuterB() {} 
}; 

// 인라인의 ctor와 dtor

당신의 이름을 숨기기 위해 형식 정의를 사용하는 경우를 방지하기 EDIT 내 데모 코드 컴파일 적어도 리스너 링크 :

// 헤더

class OuterA 
{ 
    public: 
    class Listener 
    { 
     public: 
     Listener(); 
     virtual ~Listener() = 0; 
    }; 

    OuterA(); 
    ~OuterA(); 
}; 

class OuterB : public OuterA::Listener 
{ 
    public: 
    class Listener 
    { 
     public: 
     Listener(); 
     virtual ~Listener() = 0; 
    }; 

    OuterB(); 
    ~OuterB(); 
}; 

// 구현

OuterA::OuterA(){} 
OuterA::~OuterA(){} 

OuterA::Listener::Listener(){} 
OuterA::Listener::~Listener(){} 

typedef OuterB::Listener BListener; 

OuterB::OuterB() {} 
OuterB::~OuterB(){} 

BListener::Listener(){} 
BListener::~Listener(){} 
+0

불행하게도 생성자와 소멸자를 인라인으로 선언하지 않으면 연결시 심볼이 중복됩니다. 인라인으로 선언하는 것은 코딩 규칙을 위반하기 때문에 가능하지 않습니다 (QAC에서 확인). – starblue

+0

나는이 같은 수수께끼를 좋아하기 때문에 다른 트릭을 시도했다. 이름을 숨기기 위해 typedef를 사용했다. –

+0

니스, 다음주에 시도해 보겠다. – starblue

관련 문제