多重虚拟继承歧义

Multiple virtual inheritance ambiguity

本文关键字:歧义 继承 虚拟      更新时间:2023-10-16

最好用一个例子来解释:

struct A
{
    virtual void foo() = 0;
};

struct B
{
    virtual void foo() = 0;
};

struct C : A, B
{
    // Implementation of A::foo
    void A::foo();
    // Implementation of B::foo
    void B::foo();
};

// Define here; howto?

我知道我可以定义与类内联的函数,但这在这种情况下是不可行的(有大约6个基类实现所有40+方法)

,

显然我没有讲清楚。直接的问题是:如何在不引起歧义问题的情况下定义继承的foo()方法?

void C::foo() { /* etc */ } 

这将定义A::foo()的实现,但B::foo()呢?请记住,我不希望在c的声明中定义方法。

注:,以这种方式建模问题的原因是预先定义的(COM/OLE)

,

这是很好的(MSVC),尽管内联:

struct A { virtual int foo() = 0; };
struct B { virtual int foo() = 0; };
struct C : A, B
{
    int A::foo() { return 1; }
    int B::foo() { return 2; }
};

void main()
{
    C* p = new C();
    cout << ((A*) p)->foo();
    cout << ((B*) p)->foo();
}

您不能为两个在两个基类中定义了相同签名的函数提供单独的覆盖。(你也不能像你认为的那样,在类中内联地定义它们)。

一种可能是引入中间基类来重命名函数:

struct ABodge : A
{
    void foo() {A_foo();}
    virtual void A_foo() = 0;
};
struct BBodge : B
{
    void foo() {B_foo();}
    virtual void B_foo() = 0;
};
struct C : ABodge, BBodge
{
    void A_foo();
    void B_foo();
};

或者,可以通过组合两个内部类来避免多重继承,每个内部类实现一个基类接口:

class C
{
public:
    // Could probably be defined as `operator A&()`, etc. to look more like
    // inheritance, but I usually prefer conversions to be explicit.
    A       & asA()       {return a;}
    A const & asA() const {return a;}
    B       & asB()       {return b;}
    B const & asB() const {return b;}
private:
    // These might need back-references to the 'C' that contains them.
    struct AImpl : A {void foo();} a;
    struct BImpl : B {void foo();} b;
};

工作正常:

struct A { virtual void foo() = 0; };
struct B { virtual void foo() = 0; };
struct C : A, B { virtual void foo(); };
void C::foo() { }

对于任何C x;, static_cast<A&>(x).foo()static_cast<B&>(x).foo()都将按预期调用x.foo(),这正是AB的纯虚接口所承诺的。