虚函数:特殊函数的讨论
来源:互联网 发布:河南省网络教研室 编辑:程序博客网 时间:2024/05/21 07:12
构造函数和析构函数
正如我们所见,在构造和析构过程中,有时需要初始化一些隐藏的成员变量。最坏的情况下,一个构造函数要执行如下操作:
1 * 如果是“最终派生类”,初始化vbptr成员变量,调用虚基类的构造函数;
2 * 调用非虚基类的构造函数
3 * 调用成员变量的构造函数
4 * 初始化虚函数表成员变量
5 * 执行构造函数体中,程序所定义的其他初始化代码
(注意:一个“最终派生类”的实例,一定不是嵌套在其他派生类实例中的基类实例)
所以,如果你有一个包含虚函数的很深的继承层次,即使该继承层次由单继承构成,对象的构造可能也需要很多针对虚函数表的初始化。
反之,析构函数必须按照与构造时严格相反的顺序来“肢解”一个对象。
1 * 合成并初始化虚函数表成员变量
2 * 执行析构函数体中,程序定义的其他析构代码
3 * 调用成员变量的析构函数(按照相反的顺序)
4 * 调用直接非虚基类的析构函数(按照相反的顺序)
5 * 如果是“最终派生类”,调用虚基类的析构函数(按照相反顺序)
在VC++中,有虚基类的类的构造函数接受一个隐藏的“最终派生类 标志”,标示虚基类是否需要初始化。对于析构函数,VC++采用“分层析构模型”,代码中加入一个隐藏的析构函数,该函数被用于析构包含虚基类的类(对于 “最终派生类”实例而言);代码中再加入另一个析构函数,析构不包含虚基类的类。前一个析构函数调用后一个。
虚析构函数与delete操作符
假如A是B的父类,
A* p = new B();
如果析构函数不是虚拟的,那么,你后面就必须这样才能安全的删除这个指针:
delete (B*)p;
但如果构造函数是虚拟的,就可以在运行时动态绑定到B类的析构函数,直接:
delete p;
就可以了。这就是虚析构函数的作用。
实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
考虑结构V和W。
析构函数可以为虚。一个类如果有虚析构函数的话,将会象有其他虚函数一样,拥有一个虚函数表指针,虚函数表中包含一项,其内容为指向对该类适用的虚析构函数的地址。这些机制和普通虚函数相同。 虚析构函数的特别之处在于:当类实例被销毁时,虚析构函数被隐含地调用。调用地(delete发生的地方)虽然不知道销毁的动态类型,然而,要保证调用对该类型合适的delete操作符。 例如,当pv指向W的实例时,当W::~W被调用之后,W实例将由W类的delete操作符来销毁。
译者注:
- V没有定义delete操作符,delete时使用函数库的delete操作符;
- W定义了delete操作符,delete时使用自己的delete操作符;
- 可以用全局范围标示符显示地调用函数库的delete操作符。
为 了实现上述语意,VC++扩展了其“分层析构模型”,从而自动创建另一个隐藏的析构帮助函数——“deleting析构函数”,然后,用该函数的地址来替 换虚函数表中“实际”虚析构函数的地址。析构帮助函数调用对该类合适的析构函数,然后为该类有选择性地调用合适的delete操作符。
- 虚函数:特殊函数的讨论
- 虚函数相关讨论
- 关于虚函数的精华讨论
- 关于虚函数的精华讨论
- 关于虚函数表的一些讨论
- 一个特殊的函数
- JavaScript的特殊函数
- JavaScript的特殊函数
- 【JS】【特殊的函数】
- 讨论invert函数的效率。
- C#构造函数的讨论
- 关于printf函数的讨论
- 归一化函数mapminmax的讨论
- 虚函数讨论---vc&汇编
- 特殊函数
- 特殊函数
- 函数名是个特殊的咚咚
- python 特殊函数的用法
- php抓取网页的基本操作
- 算法提高 队列操作
- 浅析 Hinton 最近提出的 Capsule 计划
- 个人如何发表国家级期刊
- HDU 1702ACboy needs your help again!
- 虚函数:特殊函数的讨论
- mysql 用localhost能登录:ip不能登录,他人无法用ip连接
- fragment 中使用 Toast经常报空指针的原因与解决
- UVA 11059:Maximum Product
- SPP-Net:让 CNN 实现任意尺寸图像输入
- 冒泡排序
- 职场感悟————转
- 深入浅析同源策略和跨域访问
- NOIP2017提高组总结