2011-03-28 20 views
0

何時在多重繼承中出現歧義?何時在多重繼承中出現歧義?

+0

請稍候。也許是例子? etc – 2011-03-28 12:47:00

+2

取決於什麼是模糊的。您可以擁有鑽石繼承,並且具有多次繼承的相同基類。或者,您可以擁有多個具有公共/受保護成員變量/函數且名稱相同的基礎,需要明確的訪問權限。 – Erik 2011-03-28 12:49:00

+0

這是一個您希望在發佈問題之前進行更多研究的場所。如果問題清晰,答案將以這樣一種方式讓你更深入地瞭解你正在尋找的東西。 – sjsam 2014-06-17 08:52:32

回答

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

一個著名的例子就是所謂的鑽石問題。

Summary: 「在具有多重繼承和知識組織的面向對象編程語言中,當兩個類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 
{ 
}