2010-11-26 14 views
11

나는 이보다 훨씬 복잡한 클래스 구조를 가지고 있지만 본질적으로 문제를 끓여 내 시나리오를 설명합니다. 순수한 가상 기본 클래스를 구현하는 두 클래스 인 A & B가 있습니다. 공유하는 다음 공통 조상, 그리고 마지막으로 & B를 할 수있는 COM-단정 세 번째 클래스 C, 순수 가상 기본의 일반적인 방법 채워 템플릿 클래스 :추상 기본 클래스의 모호한 상속 :

struct I { 
    virtual void r()=0; 
}; 

struct A : I {}; 
struct B : I {}; 

struct C : A, B { 
    void q(){ 
    r();    // the problem is here. 
    } 
}; 

struct D : C { 
    virtual void r(){ 
    } 
}; 

C* c = new D; 
c->q(); 

내 문제는, 내가 할 수있는 것입니다 r()를 호출하기 위해 C :: q를 얻는 방법을 알지 못한다.

void C::q(){ 
    r(); // is ambiguous 
    A::r(); // is pure virtual 
    B::r(); // also is pure virtual 
    D::r(); // C doesn't know about D 
    ((D*)this)->r(); // is dubious and requires C to know about D. 
} 

올바른 가상 메서드가 호출되도록 C에서 r() 메서드를 호출하려면 어떻게해야합니까?


죄송합니다. 여기서 가상 계승을 사용할 수 없음을 분명히해야합니다. 모두가 모든 것을 해결하기 위해 충분히() R에 대한 호출을 명확하게 나타납니다

struct C : A, B { 
    virtual void r()=0; 
    ... 

또는

struct C : A, B { 
    using A::r; 
    ... 

: 나는 두 가지 해결책을 발견했다.

는 C에서
+6

+1 귀하의 문제를 해결하고 가장 단순한 형태로 분해하십시오. –

+0

r()이 가상 상속없이 C에서 모호하지 않습니까? – DumbCoder

+0

가상 기본 클래스 또는 추상 기본 클래스를 의미합니까?'I' 가상베이스를 만들기 위해서는'struct A : virtual I {};과'struct B : virtual I {}; '이 필요합니다. –

답변

4

재 선언 방법 연구 등 순수 가상 :

struct C : A, B { 
    void q(){ 
    r();    // the problem is here. 
    } 

    virtual void r()=0; 
}; 
+1

이것이 왜 허용 된 대답인지 확실하지 않습니다. 그것은 해킹입니다. 정답은 사실상 I에서 이어집니다. – T33C

+0

일반적으로 동의합니다. 그러나 제 상황에서는 가상 상속을 사용할 수 없습니다. 모든 비 가상 상속 솔루션 중에서 가장 우아합니다. –

2

계층 구조의 일부가 수행하도록 컴파일러에 알려주기 :

struct C : A, B { 
    void q(){ 
    A * p = this; 
    p->r();    // recent GCC compiles this 
    } 
}; 
3

시도 가상 상속

struct A : virtual I {}; 
struct B : virtual I {}; 
2

그것은 모호한 컴파일러는 어떤 r()을 호출할지 알지 못하기 때문에 A 또는 one com에서 오는 호출 B.

에서 쉬운 방법을 보내고은 작성하는 것입니다 :

static_cast<A*>(this)->r(); 

또는

static_cast<B*>(this)->r(); 

그러나 나는이 중 어느 것도 당신이 찾고있는 답이 없다고 생각합니다. 당신은 인터페이스를 virtual를 통해 I를 상속하여 상황을 정리 : 사용자가 예상하는대로

struct A : virtual I {}; 
struct B : virtual I {}; 

지금, 당신은

void C::q() { r(); } 

를 호출 할 수 있습니다. 간단한에 대한 설명은 가상을 사용함으로써 클래스 C가 인터페이스 I의 두 개가 아닌 "복사"하나만 가져옵니다. 이렇게하면 코드가 불분명 해집니다.

+0

static_cast가 아닌 dynamic_cast를 사용해야합니까? 관련된 가상 기능이 있습니다. – DumbCoder

+0

아니요, 당신은 계층 구조를 상향시킬 것입니다, 하향식은 아닙니다. – Simone

-1

자식 구조체에 r()을 오버로드하지 않았으므로 여전히 순수 가상입니다. 즉 구현이 없습니다.

+0

아니, 그게 문제가 아니야. – Simone

관련 문제