2011-05-03 4 views
8

흥미로운 다중 상속 문제를 파악하려고합니다.C++ 다중 상속 - 왜 작동하지 않습니까?

class A 
{ 
public: 
    virtual int foo() = 0; 
    virtual int bar() = 0; 
}; 

는 그런 부분이 인터페이스를 완료하는 추상 클래스가있다 :

조부모는 다양한 방법과 인터페이스 클래스이다.

class B : public A 
{ 
public: 
    int foo() { return 0;} 
}; 

class C : public A 
{ 
public: 
    int bar() { return 1;} 
}; 

내가 부모 모두로부터 상속을 사용하려는 클래스는 방법을 사용하여 지침을 통해 어디서 무엇인지를 지정한다 : 나는 DI가 시도에 대한 오류를 얻을 인스턴스화하려고

class D : public B, public C 
{ 
public: 
    using B::foo; 
    using C::bar; 
}; 

abstract 클래스를 인스턴스화합니다.

int main() 
{ 
    D d; //<-- Error cannot instantiate abstract class. 

    int test = d.foo(); 
    int test2 = d.bar(); 

    return 0; 
} 

누군가가 문제를 이해하고 부분 구현을 최대한 활용하는 데 도움을 줄 수 있습니까?

+2

다이아몬드 패턴에서는 가상 상속을 사용해야합니다. 그러나 나는 그것이 당신의 문제를 스스로 해결할 것이라고는 생각하지 않습니다. – David

답변

13

다이아몬드 상속이 없습니다. BC 기본 클래스 인 D은 각각 A에서 상속하지 않으므로 기본 클래스 하위 개체 인 A을가집니다. C에서 A::fooA::barB에서와 A::fooA::bar :

그래서, D에, 정말 구현해야 네 순수 가상 멤버 함수가 있습니다.

가상 상속을 사용하고 싶을 것입니다. 클래스 선언과 기본 클래스 목록과 같이 보일 것이다 :

class A 
class B : public virtual A 
class C : public virtual A 
class D : public B, public C 

당신은 다음 D에 다른 두 순수 가상 함수를 오버라이드 (override) 할 필요가 가상 상속을 사용하지 않으려면 :

class D : public B, public C 
{ 
public: 
    using B::foo; 
    using C::bar; 

    int B::bar() { return 0; } 
    int C::foo() { return 0; } 
}; 
-2

그들이 상속받을 수 있도록 기본 클래스 virtual을 만들어야합니다. 일반적으로 모든 비공개 멤버 함수와 기본 클래스는 virtual이어야합니다. 수행중인 작업을 알고 있고 해당 멤버/기반에 대한 일반 상속을 사용하지 않도록 설정해야합니다.

+1

"일반적인 규칙은 모든 public 멤버 함수와 기본 클래스가 가상이어야한다는 것입니다."뭐라구? 누구의 일반적인 규칙입니까? 가상 멤버 함수에 관한 일반적인 규칙은 비공개로 만들고 비공개 멤버 함수는 비공개 가상 멤버 함수를 호출합니다 (GotW 기사 [ "Virtuality"] (http : // www.gotw.ca/publications/mill18.htm)). 가상 기본 클래스에 관해서 ... 나는 가상의 상속을 사용해야한다는 지난 몇 년 동안의 한 사례에 대해서만 생각할 수 있습니다. –

+0

@JamesMcNellis "지난 몇 년 동안 가상 상속을 사용해야하는 사례가 한 번만 있다고 생각할 수 있습니다 ._"가상 복제를 사용하기 위해 몇 번이나 사용 했습니까? – curiousguy

+0

@JamesMcNellis : 그 기사는 대개 전체 학사입니다. 그것이 옳다는 유일한 사실은 대부분의 멤버 기능 (가상 또는 비공개)이 사적이어야한다는 것입니다. 공개가 아닌 가상 멤버 함수를 갖는 것은 재앙을 기다리고 있으며 기본적으로 클래스를 서브 클래 싱 할 수 없다는 것을 의미합니다. –