简体   繁体   English

多重虚拟继承的歧义

[英]Multiple virtual inheritance ambiguity

Probably best explained with an example: 最好用一个例子来解释一下:

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?

I'm aware I can define the functions inline with the class however that's not feasible in this instance (there are about 6 base classes to implement all with 40+ methods) 我知道我可以定义与类内联的函数,但是在这种情况下不可行(大约有6个基类可以使用40多种方法实现所有功能)

-- -

Apparently I wasn't clear enough. 显然我还不够清楚。 The question directly is: How to define both foo() methods that have been inherited without causing ambiguity issues? 直接的问题是:如何定义两个继承的foo()方法而不会引起歧义问题?

The following does indeed work 以下确实有效

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

This will define the implementation of A::foo() yet what of B::foo() ? 这将定义A :: foo()的实现,而B :: foo()的实现是什么? Bearing in mind I do not wish to define the methods within the declaration of C. 请记住,我不想在C声明中定义方法。

PS, the reason for modelling the problem this way at all is predefined (COM/OLE) PS,完全以这种方式对问题建模的原因是预先定义的(COM / OLE)

-- -

This is fine (MSVC) albeit inline: 这很好(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();
}

You can't provide separate overrides for two functions with the same signature defined in two base classes. 您不能为在两个基类中定义的具有相同签名的两个函数提供单独的替代。 (You can't define them inline within the class either, as you seem to think). (您似乎也无法在类中内联定义它们)。

One possibility is to introduce intermediate base classes to rename the functions: 一种可能性是引入中间基类来重命名功能:

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();
};

Alternatively, you could avoid multiple inheritance by composing two internal classes, each of which implement one of the base class interfaces: 另外,可以通过组成两个内部类来避免多重继承,每个内部类都实现一个基类接口:

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;
};

Works as expected: 按预期工作:

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

For any C x; 对于任何C x; , static_cast<A&>(x).foo() and static_cast<B&>(x).foo() will call x.foo() as expected, which is precisely what the pure-virtual interfaces of A and B promise. static_cast<A&>(x).foo()static_cast<B&>(x).foo()将按预期调用x.foo() ,这正是AB的纯虚拟接口所承诺的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM