关于c++多重继承与虚继承的疑问。

大漠刀客
  • 185
#include <stdio.h>
#include <iostream>
#include <map>

using namespace std;

class CBase1
{
public:
    virtual void Test1() = 0;
};

class CBase2 {
public:
    virtual void Test2() = 0;
    virtual void Test3() = 0;
};

class CMD : public CBase1,  public CBase2
{
public:
    void Test1() {
        cout << "11" << endl;
    }
    void Test2() {
        cout << "22222" << endl;
    }
    void Test3() {
        cout << "33" << endl;
    }

};


int main(  ) {

    CMD obj;
    CBase1 *pBase1 = &obj;
    pBase1->Test1();
    CBase2 *pBase2 = (CBase2*)pBase1;
    pBase2->Test2();
    pBase2->Test3();

}

这里为什么输出两次11 之后停下了。
多重继承不是会继承所有父类的成员吗,pBase2->Test2()为什么调用的还是Test1()函数。
这里需要用虚表修改么?

回复
阅读 1.7k
2 个回答
✓ 已被采纳

CBase2 *pBase2 = (CBase2*)pBase1;

pBase1CBase1 * ,而 CBase1CBase2 没有任何直接关系。

要完成这个转换,必须考虑 pBase1 指向对象的动态类型,即 pBase1 实际指向的是一个CMD的对象。要在类型转换中考虑动态类型,就必须要用 dynamic_cast.

这个转换改成这样就好了:CBase2 *pBase2 = dynamic_cast<CBase2*>(pBase1);

注1: dynamic_cast 进行这种转换需要源指针指向一个 polymorphic type(至少有一个虚函数)。你这里正好有。
注2:原始写法会使用reinterpret_cast,然后后续对指针的使用会触发未定义行为。

clipboard.png

  1. 首先无论是CMD,CBase1,CBase2都维护着自己的虚函数表
  2. 当类集成时,虚函数表中会覆盖原有的虚函数表位置的内容,如上图所示中,CMD继承自CBase1,当将CBase1 *指向CMD时,他其实访问的是CBase1虚函数表,这是虚函数表中只有一个CMD:Test1()方法
  3. 而如果将CBase1转换成CBase2时,是无法产生多态的,因为两个虚函数表没有覆盖操作

这里是我浅显的理解,希望能帮助到你。

宣传栏