c++ - 当类的多重继承本身在其层次结构中具有菱形继承时,功能继承不明确

标签 c++ inheritance multiple-inheritance virtual-inheritance msvc12

文字描述(下面的代码):我有一个提供类集合的库。对于每组类,我们有两个具体类型,(ClassA_Partial, ClassA), (ClassB_Partial, ClassB)等。这些分别实现(Interface_PartialInterface)。此外,Interface 是一个 Interface_Partial 并且每个Class? 是一个 Class?_Partial - 创建一个菱形继承模式,其中顶部是虚拟继承的。

为什么在同时继承 ClassAClassB 时,Interface_Partial 函数不明确?

struct Interface_Partial
{ 
    virtual ~Interface_Partial(); 
    virtual void f() = 0;
};

struct Interface
    :
    virtual Interface_Partial
{
    virtual void g() = 0;
};


struct ClassA_Partial : public virtual Interface_Partial
{
    void f() {};
};


struct ClassA : public Interface, public virtual ClassA_Partial
{
    void g() {};
};

struct ClassB_Partial : public virtual Interface_Partial
{
    void f() {};
};


struct ClassB : public Interface, public virtual ClassB_Partial
{
    void g() {};
};

struct MyClass : public ClassA, public ClassB
{ }; // error C2250: MyClass : ambiguous inheritance of 'void Interface_Partial::f(void)'

当我们多次继承一个公共(public)接口(interface)时,为什么我们不能像通常那样消除歧义?例如

struct ClassX : public Interface_Partial { void f() {} };
struct ClassY : public Interface_Partial { void f() {} };
class Another : public ClassX, public ClassY
{};

void func()
{
    // This is ok
    Another a;
    a.ClassX::f();   

    // Why would this not work?
    // unambiguously refers to the one and only f() function 
    // inherited via  ClassA
    MyClass b;
    b.ClassA::f();   
}

最佳答案

由于虚继承,基类Interface_Partial只有一个虚表——一旦你使用虚继承,“虚”会感染所有级别的所有派生类

继承是不明确的,因为 MyClass 有两个不同版本的 f() 可用 - 一个来自 ClassA,一个来自 ClassB。由于 Interface_Partial 的虚拟继承,您有两个处于同一级别的派生类实现并试图覆盖相同的虚函数。声明一个虚基类使得所有派生类共享虚基类,包括它的虚表。共享虚表得到更新以包含应调用的虚函数的指针。但由于有两个同样“好”的可供选择,因此无法从另一个中选择一个。

在您给出的另一个示例中,Interface_PartialClassXClassY 的非虚拟基类,因此每个类都覆盖了一个完全不同的虚函数。这对编译器来说是明确的,尽管当您调用它们时,您必须指定要调用哪个特定的 f()

您可以通过在 MyClass 中提供 f() 的实现来解决此问题。

关于c++ - 当类的多重继承本身在其层次结构中具有菱形继承时,功能继承不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28556872/

相关文章:

c++ - 内联在基类主体内声明但通过派生类调用的函数

c++ - 提升 asio set_option 错误

c++ - C++中的静态和动态解析

java - 这是将 Java 接口(interface)转换为 Scala 的正确方法吗?

Python 多重继承元类错误

c++ - 为什么虚基多重继承只调用基类默认构造函数?

python - python 中的组合和外观是同一件事吗?

c++ - 如何编写要在 main() 获得控制权之前执行的代码?

c++ - 以下包扩展有什么问题?

javascript - Node JS 中的原型(prototype)继承