Virtual Member Functions(虚拟成员函数)
实现模型:每一个class 只会有一个virtual table,内含该class之中有作用的virtual function的地址,每一个object有一个vptr(多继承可能有多个),指向virtual table的所在。
虚函数的地址以及存放虚函数地址的虚表在编译时期就确定下来了,不需要执行期的介入。执行期要做的是,激活虚函数
1.单一继承
单一继承的原理:
①继承基类的虚函数实体:基类所有虚函数实体的地址会被拷贝到derived class的virtual table相对应的slot之中。
②重写基类的虚函数实体:将自己的函数实体地址放到虚表对应的slot中。
③新加入的virtual function:virtual table的尺寸增大一个slot,新的函数实体地址放进该slot之中。·
2.多继承下的virtual Functions
有多少个基类,派生类就会有多少个虚表以及指向虚表的虚指针
class Base1
{public:Base1();virtual ~Base1();virtual void speakClear();virtual Base1* clone()const;protected:int Data1;
};class Base2
{public:Base2();virtual ~Base2();virtual void Mumble();virtual Base2* clone()const;protected:int Data2;
};class Derived : public Base1, public Base2
{public:Derived();virtual ~Derived();virtual Derived* clone()const;protected:int Data3;
};
①我们来看一下Derived对象模型
我们来看一下
clone这个在虚函数在派生类中被重写了,但是这个函数只会覆盖第一个继承的基类,在覆盖第二个基类的时候报错了,无法进行转换
error C2440: “return”: 无法从“Derived *”转换为“Base2 *”。
派生类的析构函数覆盖了其基类的析构函数
哪怕我们在派生类中添加新的虚函数,也只会出现在第一个虚函数指针指向的那个虚函数表中
还需注意的一点 第二个派生类的this &thunk: this-=8; goto Derived::{dtor}
当我们用一个Base2的指针去指向一个派生类,然后去delete它,this指针就需要做这个调整
②书中的图片和VS中略有不同
以下三种情况需要调整指针:
派生类指针指向派生类对象,使用虚表1,访问虚表2的函数时。
base2基类的指针指向派生类对象,调用析构函数。
派生类对象虚函数执行的返回值是派生类指针,赋给base2基类指针
3.虚拟继承下的virtual Functions
class Point2d
{public:Point2d(int x = 10, int y = 20) : _x(x), _y(y) {}virtual ~Point2d();virtual void Mumble();virtual int Z();protected:int _x, _y;
};class Point3d : public virtual Point2d
{public:Point3d(int x = 10, int y = 20, int z = 30) :Point2d(x, y), _z(z) {}~Point3d();int Z();protected:int _z;
};
①对象模型
我们可以看到虚基类指针和成员变量Z放在对象模型的开头,他们两个是不变的部分,然后是4个字节的vtordisp我前面写过,下来是虚继承的部分
Virtual Member Functions(虚拟成员函数)相关推荐
- C++——虚函数(Virtual Member Functions) 【functions语意学】
单继承下的虚函数 虚函数的实现: 为每个有虚函数的类配一张虚函数表(virtual table),它存储该类类型信息和所有虚函数执行期的地址. 为每个有虚函数的类插入一个指针(vptr),这个指针指向 ...
- 为什么虚函数(virtual)不能是static函数
简而言之,成员函数实例相关,静态函数类相关. 虚函数,是一种特殊的成员函数,用来实现运行时多态. 静态成员函数,可以不通过对象来调用,没有隐藏的this指针. virtual函数一定要通过对象来调用, ...
- C++的特殊成员函数(special member functions)及其生成规则
特殊成员函数(Special member functions)是指那些编译器可以为类自动产生的函数. C++ 中有五种特殊成员函数(special member functions): 1. 默认构 ...
- [C++]Call virtual member function in constructor or destructor
嗷嗷按,今天被问到在constructor/destructor中调用virtual member function的问题.答错了,很羞耻. 依稀记得在constructor/destructor调用 ...
- NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. ...
- UE3 Light Functions (光照函数)
Light Functions (光照函数) Light Functions (光照函数) 概述 Decals(贴花) vs 光照函数 可以使用哪些材质表达式? Texture 2D(二维贴图) Te ...
- UE4 Light Functions(光源函数)
概述 Light Functions(光源函数) 从本质上讲是一种可以应用到光源上的材质,应用起来和投影仪或光源凝胶类似.通过使用虚幻引擎材质编辑器的强大功能,光源函数可以塑造光源形状.创建有趣的阴影 ...
- Python:实现scoring functions评分函数算法(附完整源码)
Python:实现scoring functions评分函数算法 import numpy as np# Mean Absolute Error def mae(predict, actual):pr ...
- 【学习笔记】C++ 中的 virtual 关键字与虚函数
目录 先决条件 前言 演示示例 virtual 关键字的作用 虚函数的规则 参考与拓展 深入拓展 先决条件 了解 C++ 中的多态这个概念. 前言 virtual 关键字是面对对象中,用于修饰类中的成 ...
- Python:实现word frequency functions词频函数算法(附完整源码)
Python:实现word frequency functions词频函数算法 import string from math import log10 def term_frequency(term ...
最新文章
- 设计模式----模板方法模式UML和实现代码
- html5中加入音频,使用HTML5在网页中嵌入音频和视频播放的基本方法
- u-boot nand flash read/write cmd
- usb转并口支持linux,使用PCI转并口实现SJF刷写嵌入式开发板
- mysql 双主 脑裂_MySQL双主(主主)架构方案
- java面试题整理_2018年最新java面试题整理。。。持续更新中。。。
- 15款最佳的 jQuery 分步引导插件
- 博文视点读书节第六日丨产品大咖书单阿里云专家直播预告,更有超值代金券手慢无
- VRRP技术原理与注意点
- Android中生成库文件与移除以及导入jar包重复问题
- 瑞禧分享二维晶体表征介绍及定制SnPSe3晶体;CoBi4Te7 磁性拓扑绝缘体/CuInP2S6晶体;Nb2SiTe4晶体/Sb2TeSe2晶体等
- mysql配置文件(完整版)
- (25)梯度下降法求解曲面极小值
- 国内硕士申请加拿大计算机博士难度,加拿大硕士和博士真的那么难申请吗?
- VPX SRIO交换板VPX3U-1Swit-CPS1848
- 【优化】1338- 分享一下图像优化原理
- 《Android 应用 之路》一个类似今日头条的APP
- navicat导入excel表中数据出错问题
- 使用Hydra通过ssh破解密码
- BigDecimal 保留两位小数