Diamond-inheritance场景在G ++中编译很好,但在VC++/Eclipse中产生警告/错误

Tib*_*ibi 14 c++ oop class multiple-inheritance virtual-inheritance

我有一个基类'Base',这是一个纯虚拟类:

class Base {

public:
    virtual void A() = 0;
    virtual void B() = 0;

    virtual ~Base() { } // Eclipse complains that a class with virtual members must have virtual destructor
};
Run Code Online (Sandbox Code Playgroud)

我还有另外两个类,其中一个实现了A(),另一个实现了B():

class DerivedA : public virtual Base
{
public:
    virtual void A() {
        printf("Hello from A");
    }
};

class DerivedB : public virtual Base
{
public:
    virtual void B() {
        printf("Hello from B");
    }
};
Run Code Online (Sandbox Code Playgroud)

声明中的虚拟关键字应解决钻石问题.

现在我想将这两个类组合成另一个类,以便实现A()和B(),如下所示:

class DerivedC: public DerivedA, public DerivedB {
     // Now DerivedA and DerivedB are combined
};

// Somewhere else in the code
DerivedC c;
c.A();
c.B();
Run Code Online (Sandbox Code Playgroud)

问题: 即使G ++编译代码很好,Eclipse也会出错:The type 'DerivedC' must implement the inherited pure virtual method 'Base::B'.使用visual studio进行编译时,我收到2条警告:

warning C4250: 'DerivedC' : inherits 'DerivedB::DerivedB::B' via dominance
warning C4250: 'DerivedC' : inherits 'DerivedA::DerivedA::A' via dominance
Run Code Online (Sandbox Code Playgroud)

所以问题是:这样做的正确方法是什么?上面的代码是否会产生未定义的行为?

注意:标题可能有点误导,我不知道这个问题的好标题是什么.

Alo*_*ave 8

这样做的正确方法是什么?上面的代码是否会产生未定义的行为?

代码完全有效.这里没有未定义的行为.通过类对象
的非限定调用将始终调用,而通过类对象的非限定调用将始终调用实例.A()DerivedCDerivedA::A()B()DerivedCDerivedB::B()

Visual C++为您提供警告,因为您的代码使用了一个不太常见的虚拟继承功能,这对大多数普通用户来说可能并不明显,并且可能会让他们感到惊讶.在这种情况下,警告应该被视为信息性的Nitpick而不是警告.

请注意,C++标准不会限制编译器为完全有效的代码发出信息警告.警告C4250的文档提供了一个示例,告诉您为什么Visual C++选择提供此警告.

  • 关于支配地位的正式规范可能并不广为人知,但结果却是人们直觉所期望的.它是广泛使用的mixin技术的基础.警告完全是愚蠢的.(但Visual Studios允许逐个关闭警告,因此您可以关闭此警告.) (3认同)

Bat*_*hyX 6

你可能想试试这个:

class DerivedC: public DerivedA, public DerivedB {
public:
    using DerivedA::A;
    using DerivedB::B;
};
Run Code Online (Sandbox Code Playgroud)

我自己无法使用Eclipse或VC++进行测试...