c++ - 虚拟和非虚拟继承的混合

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

在尝试更深入地分析 C++ 的继承机制时,我偶然发现了以下示例:

#include<iostream>

using namespace std;

class Base {
public:
    virtual void f(){
    cout << "Base.f" << endl; 
    }
};

class Left : public Base { //NOT VIRTUAL!!!
public:
void g(){ 
        f();
    }     
};

class Right : public Base{
public:
    virtual void f(){
    cout << "Right.f" << endl; 
    }
};

class Bottom : public Left, public Right{
public:
    Bottom(int arg){ }
    //void f() { }
};

int main(int argc,char **argv)
{
    Bottom* b = new Bottom(23);
    b->g();
}

调用很明显

b->f()

是不明确的,所以对象 Bottom 上没有唯一的方法 f()。现在,调用

b->g()

工作正常并打印

Base.f

嗯,据我所知:

  1. 静态类型是 Bottom,所以我们调用它的 g() 方法,因为它是非虚拟的
  2. g()方法继承自Left,所以我们称这个继承方法
  3. 现在,Left 中的g() 尝试调用虚方法f()。根据 C++ 规范,我们调用动态类型指针(即 Bottom)的 f() 方法

但 Bottom 没有方法 f()... 至少不是唯一的。为什么这个程序执行 Left::Base::f() 而不是 Right::Base::f() 或者为什么它只是不声明调用 f() 与 Bottom 有歧义吗?

最佳答案

简短的回答是(如您所述),Bottom 没有方法 f(),因此没有必要尝试调用它。

Bottom 包含两个子对象 LeftRight。它们每个都继承自 Base,因此 Bottom 包含成员函数 Left::f()Right::f() ,但没有 Bottom::f()。由于 Bottom 不会覆盖 Left::f()(例如使用 Right::f()),Base::f()Left::g() 中唯一的最终覆盖器。

比照。来自 C++03 标准的 10.3.9 中的示例。

关于c++ - 虚拟和非虚拟继承的混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10166313/

相关文章:

design-patterns - 为什么是死亡钻石而不是死亡三角形

c++ - 在 Boost 的多索引容器中获取非常量迭代器

c++ - 调用unique_ptr子类继承的模板构造函数

c++ - C++中多重继承对象的内存布局

c# - 在同一个类上多次使用通用接口(interface)

c# - 从基类调用事件

c++ - <<< >>> vscode 中的 cuda

c++ - 调试断言失败! (c++)

c++ - 如何有效地检查/限制 sqlite 数据库的大小?

java - Brief : Some game objects move, 有些没有