动态多态原理浅析(C++)

前言

多态主要分为两类:

  • 静态多态:地址早绑定,即编译阶段确定函数地址,例如函数重载运算符重载
  • 动态多态:地址晚绑定,即运行阶段确定函数地址

动态多态

使用条件

父类指针或引用指向子类对象

基础语法

引入一段代码示例:

#include<iostream>
using namespace std;
class Animal
{
public:
    void speak()
    {
        cout << "动物在叫" << endl;
    }
};
class Cat :public Animal
{
public:
    void speak()
    {
        cout << "猫在叫" << endl;
    }
};
void doSpeak(Animal& animal)    //Animal& animal = cat
{
    animal.speak();     //地址早绑定
}
void test01()
{
    Cat cat;
    doSpeak(cat);   //父类引用/指针指向子类对象
    cout << "Animal类占用内存:" << sizeof(Animal) << endl;
}
int main()
{
    test01();
    system("pause");
}

运行结果为:

file

程序期望输出Cat类的speak方法,也即输出内容为猫在叫

可以看到实际输出与期望不符,原因是speak()在编译阶段已经确定了地址,无法通过父类指针指向子类对象,解决思路即是将早绑定改为晚绑定,让speak()在运行阶段正确指向子类对象,将Animal类的代码改成如下:

class Animal
{
public:
    virtual void speak() //virtual修饰后变成虚函数
    {
        cout << "动物在叫" << endl;
    }
};

修改后的运行结果为:

file

加入virtual关键词后,speak()变为虚函数,子类中的speak()无需添加virtual关键字(但也为虚函数)

此时speak()正确指向Cat类,由此可以得出多态满足的条件:

  • 有继承关系
  • 子类重写父类中的虚函数

修改之前的Animal类占用内存为1字节,说明此时为空类(空类占用1字节),修改之后的占用变为4字节,可知加入virtual关键词后,类内部结构发生了变化,不难猜出此时类中存在一个指针

实现原理

为了直观看到Animal类内部结构,借助VS自带的命令提示工具,到源文件存放目录后运行cl /d1 reportSingleClassLayoutAnimal test.cpp,结果如下:

file

可以看到类内存在一个大小为4的vfptr,也即是virutal function pointer-虚函数(表)指针,该指针指向下方的vftable,也即是virtual function table-虚函数表,该表中存放的speak()实际地址是&Animal::speak
重复上述操作,继续查看Cat类内部结构:
file

可以看到重写后,Cat类中的虚函数表内实际存储的函数地址为&Cat::speak

图示

为方便理解,另附一张示意图

file

本文作者:小小黑
本文链接:https://lonelyenderman.top/archives/818
版权声明:本站采用 BY-NC-SA 进行许可。转载请注明出处!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(*^▽^*)
 ̄﹃ ̄
(╯‵□′)╯︵┴─┴
(~ ̄▽ ̄)~
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
( ͡° ͜ʖ ͡°)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
つ﹏⊂
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
(´▽`ʃ♡ƪ)
w(゚Д゚)w
(๑•̀ㅂ•́)و✧
(#`O′)
凸(艹皿艹 )
o(≧口≦)o
≡ω≡
(*/ω\*)
○| ̄|_
(⊙ˍ⊙)
Σ(っ °Д °;)っ
o( ̄ヘ ̄o#)
<( ̄︶ ̄)>
(。・∀・)ノ゙
(o゜▽゜)o☆
╥﹏╥
ヾ(´・ω・`)ノ
😂
😀
😅
😊
🙂
😍
😘
😜
😝
😏
😒
🙄
😳
😔
😫
😱
😭
😶
🌚
😣
🤨
😣
🤐
😪
🤤
🥵
🤮
😨
😱
😓
🤬
👴
🤡
🙈
💊
🙏
🤺
💩
👻
🙌
🖕
👍
👫
👌
🙏
👀
🐒
🔪
Source: github.com/zhheo/Sticker-Heo
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
Heo
花!
上一篇
下一篇