运行时多态-虚函数
虚函数
这是C++中多态的一种呈现方式,为了更好的得以了解虚函数的本身的含义与相关意义。让我们先了解下,在C++还有那些实现多态的方案。
- 重载。允许存在多个重名函数(C语言不支持该语法)
- 覆盖。是指子类重新定义父类虚函数的做法,可通过父类的指针调用实际子类的成员函数。
虚函数表
Virtual Table
是一块连续的内存,每个内存单元记录一个JMP指令的地址类别
单继承无虚函数覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Base{
public:
virtual void func1();
virtual void func2();
virtual void func3();
}
class Derived : public Base{
public:
virtual void func4();
virtual void func5();
virtual void func6();
}
// 值得注意的点
- 虚函数按照声明顺序依次放入表中
- 父类的虚函数在子类的虚函数前面
单继承有虚函数覆盖
1 | class Base{ |
多继承无虚函数覆盖
1 | class Base1{ |
多继承有虚函数覆盖
1 | class Base1{ |
一些细节的补充,除了这些成员函数的内存分布外,还有两个额外的标志位
offset_of_top
用于表示虚表指针距离类开头的距离typeinfo for base
用于支持RTTI
虚函数常见问题
- 开销
- 带有虚函数的每个类产生一个虚函数表,用来存储虚成员函数的指针
- 每个带有虚函数的类都会有一个指向虚函数表的指针(共享同一个虚表)
- 不可以作为虚函数的函数
- 构造函数:虚表和虚指针需要通过此函数来进行构造
- 内联函数:内联函数需要在编译期完成替换,虚函数则是在运行期确定
- 静态函数:静态函数属于类而非对象,没有this指针,无法访问虚表
- 友元函数、普通函数
- 纯虚函数、虚函数
- 纯虚函数仅有声明
- 虚函数既可声明,也可定义
- 父类设置虚析构函数的意义
- 避免内存泄漏,无法释放子类对象开辟的空间
Invitation
夕阳的刻痕
781263509
created:03/09/2020
Welcome, myFriend
Use this card to join the candyhome and participate in a pleasant discussion together .
Welcome to Aker’s candyhome,wish you a nice day .
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Aker's Blog!
评论