金歌 发表于 2022-6-24 13:31:52

C++虚函数表、多态

概述

虚函数表是C++实现多态的一种方式。
问题:

[*]什么情况下C++会使用虚指针和虚函数表?
[*]如果子类不新增任何虚函数,也不重写父类的虚方法,会和父类共用一张虚函数表么?
[*]父类的构造函数为什么不能正确的调用虚函数?
C++虚函数表指针和虚函数表

创建一个Base类

class Base
{
public:
        int a;
        int b;
};查看Base内存布局

1>class Base        size(8):
1>        +---
1> 0        | a
1> 4        | b
1>        +---
为Base类添加一个虚函数

class Base
{
public:
        int a;
        int b;

        virtual void BaseFunc1()
        {
                std::cout << "Call BaseFunc1 From Base" << std::endl;
        };
};查看Derive类的内存分布

1>class Derive        size(12):
1>        +---
1> 0        | +--- (base class Base)
1> 0        | | {vfptr}
1> 4        | | a
1> 8        | | b
1>        | +---
1>        +---
1>Derive::$vftable@:
1>        | &Derive_meta
1>        |0
1> 0        | &Base::BaseFunc1
1> 1        | &Base::BaseFunc2
虚函数表的内容和父类Base一样
查看Base和Derive的虚函数表地址

https://img2022.cnblogs.com/blog/2905902/202206/2905902-20220623134959487-1416476131.png
Base和Derive并非公用一张虚函数表。
Derive重写父类Base的方法

class Derive : public Base{public:        virtual void BaseFunc1() override        {                std::cout         +---
1> 0        | +--- (base class Base)
1> 0        | | {vfptr}
1> 4        | | a
1> 8        | | b
1>        | +---
1>        +---
1>Derive::$vftable@:
1>        | &Derive_meta
1>        |0
1> 0        | &Derive::BaseFunc1
1> 1        | &Base::BaseFunc2
1>Derive::BaseFunc1 this adjustor: 0</p></blockquote>此时虚函数表的0元素被替换成了Derive::BaseFunc1的地址。
为Derive添加一个新的虚函数

class Derive : public Base{public:        virtual void BaseFunc1() override        {                std::cout0        | | {vfptr}
1> 4        | | a
1> 8        | | b
1>        | +---
1>        +---
1>Derive::$vftable@:
1>        | &Derive_meta
1>        |0
1> 0        | &Derive::BaseFunc1
1> 1        | &Base::BaseFunc2
1> 2        | &Derive::DeriveFunc1
1>Derive::BaseFunc1 this adjustor: 0
1>Derive::DeriveFunc1 this adjustor: 0</p></blockquote>Derive的虚函数表添加了一个新的函数地址。
让父类Base在构造函数中调用虚函数BaseFunc1。

class Base{public:        Base()        {                BaseFunc1();        }        int a;        int b;        virtual void BaseFunc1()        {                std::cout
页: [1]
查看完整版本: C++虚函数表、多态