2011-03-28 2 views
0

다중 상속에서 모호성이 발생하는시기는 언제입니까?다중 상속에서 애매한 점이 언제 생깁니 까?

+0

조금 더 자세히 알려주세요. 어쩌면 예를 들어? –

+2

무엇이 모호한가에 달려 있습니다. 한 번 이상 상속 된 동일한 기본 클래스를 사용하여 다이아몬드 상속을 가질 수 있습니다. 또는 액세스 권한을 명시해야하는 동일한 이름의 공용/보호 된 멤버 변수/함수가있는 여러 개의 기본 멤버를 가질 수 있습니다. – Erik

+0

질문을 올리기 전에 좀 더 많은 조사를해야 할 곳입니다. 질문에 명확성이 있다면 대답은 당신이 찾고있는 것에 더 많은 통찰력을 갖게합니다. – sjsam

답변

4

상속의 여러 경로에서 기본 클래스를 복제하고 해당 기본 형식으로 캐스팅하거나 해당 멤버 함수를 호출하려고하는 경우.

struct A { }; 
struct B : A { }; 
struct C : A { }; 
struct D : B, C { }; // has replicated A as the base class 

D d; 
A* a = static_cast<A*>(&d); // oops 

문제는 크게 상황에 따라 여러 가지 치료가

더 많은 정보 here, 특히 here (가상 기본 클래스를 사용하여, 단지 상기 캐스트 등을 수정).

1
struct Base{ 
    void foo(){ 
    } 
}; 

struct Derived1 : public Base{ 
}; 

struct Derived2 : public Base{ 
}; 

struct Final : public Derived1, public Derived2{ 
}; 

int main(){ 
    Final f; 
    f.foo(); 
} 

See on Ideone. 다음

struct Derived1 : virtual public Base{ 
}; 
struct Derived2 : virtual public Base{ 
}; 

ambigouty에 대한 또 다른 가능성은 다음과 같습니다 : 수정하려면 가상 상속을 사용 다시

struct Base1{ 
    void foo(){ 
    } 
}; 

struct Base2{ 
    void foo(){ 
    } 
}; 

struct Final : public Base1, public Base2{ 
}; 

int main(){ 
    Final f; 
    f.foo(); 
} 

Ideone에. 해결하려면, 간단하게는 Final에서 다음을 수행 : 다중 상속의 모호함의

struct Final : public Base1, public Base2{ 
    using Base1::foo; 
    // or 
    // using Base2::foo; 
}; 
3

한 유명한 예는 소위 다이아몬드 문제입니다.

요약 : 다중 상속 및 지식 조직이있는 객체 지향 프로그래밍 언어에서 다이아몬드 문제는 두 개의 클래스 B와 C가 A에서 상속 받았을 때 발생하는 모호성이며 클래스 D는 B와 C에서 상속됩니다. D의 메소드는 A에 정의 된 메소드를 호출하고 (메소드를 대체하지는 않습니다.) B와 C는이 메소드를 다르게 재정의 한 후 어떤 클래스에서 B 또는 C를 상속합니까? "

현재 세부 사항을 찾을 수 있습니다 Wikipedia: Diamond Problem

0

를가 같은 클래스가 하나 개 이상의 경로를 통해 기본 때

class baseX 
{ 
    private: 
    void* callA();//will never be ambiguous. 
    protected: 
    void* callB(); 
    public: 
    void* callC(); 
} 
class baseY 
{ 
    private: 
    void* callA();//will never be ambiguous. 
    protected: 
    void* callB(); 
    public: 
    void* callC(); 
} 
class derived: public baseX, public baseY 
{ 
    void someMethod() 
    { 
    void* x = baseX::callB();//not ambiguous 
    void* y = baseY::callB();//not ambiguous 
    void* z = callB();//ambiguose 
    } 
} 
void someFunction(derived& d) 
{ 
    void* x = d.CallC();//ambiguous 
} 

모호함도 발생할 수 불분명 사용되는 이름을 만드는 경우 :

class Base 
{ 
    public void call(); 
} 
class DerivedX : public Base 
{ 
} 
class DerivedY : public Base 
{ 
} 
class GrandChild : public DerivedX, public DerivedY //What does call() do? 
{ 
} 

가상베이스로 해결할 수 있습니다.

class Base 
{ 
    public void call(); 
} 
class DerivedX : public virtual Base 
{ 
} 
class DerivedY : public virtual Base 
{ 
} 
class GrandChild : public DerivedX, public DerivedY //only one "Base" class in inheritance, shared between DerivedX and DerivedY 
{ 
} 
관련 문제