C++ 虚函数 + 多重继承情况下,派生类对基类中同名虚函数的覆盖方式

先来看一段代码:

#include <bits/stdc++.h>
using namespace std;

class base1 {
   public:
    virtual void fun() { cout << "base1" << endl; }
    virtual ~base1() {};
};

class base2 {
   public:
    virtual void fun() { cout << "base2" << endl; }
    virtual ~base2() {};
};

class derived : public base1, public base2 {
   public:
    virtual void fun() { cout << "derived" << endl; }
    virtual ~derived() {};
};

int main() {
    derived* ptr1 = new derived;
    return 0;
}

问:derived::fun()会覆盖那个基类的同名函数?

答:会覆盖所有基类同名函数。

解析

借助分析工具,获取类布局情况,关于类布局的获取可以看这篇文章。C++虚函数表底层结构

Vtable for base1
base1::_ZTV5base1: 5 entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI5base1)
16    (int (*)(...))base1::fun
24    (int (*)(...))base1::~base1
32    (int (*)(...))base1::~base1

Vtable for base2
base2::_ZTV5base2: 5 entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI5base2)
16    (int (*)(...))base2::fun
24    (int (*)(...))base2::~base2
32    (int (*)(...))base2::~base2

Vtable for derived
derived::_ZTV7derived: 10 entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI7derived) // derived
16    (int (*)(...))derived::fun
24    (int (*)(...))derived::~derived
32    (int (*)(...))derived::~derived
40    (int (*)(...))-8
48    (int (*)(...))(& _ZTI7derived) // derived
56    (int (*)(...))derived::_ZThn8_N7derived3funEv // derived::fun()
64    (int (*)(...))derived::_ZThn8_N7derivedD1Ev // derived::~derived()
72    (int (*)(...))derived::_ZThn8_N7derivedD0Ev // derived::~derived()

Class derived
   size=16 align=8
   base size=16 base align=8
derived (0x0xb8cf9a0) 0
    vptr=((& derived::_ZTV7derived) + 16)  // 第21行
base1 (0x0xbd97180) 0 nearly-empty
      primary-for derived (0x0xb8cf9a0)
base2 (0x0xbd971e0) 8 nearly-empty
      vptr=((& derived::_ZTV7derived) + 56) // 第26行

从上可以看出,derived类有两个虚表指针,每个虚表指针指向各自的虚表,同时可以看到derived::fun()覆盖了base1::fun()base2::fun()

关于符号名称的解码,参考这篇文章:GCC生成的符号名称的还原-demangle方法

结论:

在 C++ 中,当一个派生类继承多个基类时,如果派生类中有一个函数与基类中的函数具有相同的签名,那么这个函数将会覆盖所有基类中相同签名的虚函数。

作者:WuQiling
文章链接:https://www.wqlblog.cn/c-虚函数-多重继承,派生类对类基类同名函数的覆/
文章采用 CC BY-NC-SA 4.0 协议进行许可,转载请遵循协议
暂无评论

发送评论 编辑评论


				
默认
贴吧
上一篇
下一篇