C++中虚基类在派生类中的内存布局





虚拟继承:






对于虚函数表指针和虚基类表指针:
当单继承且非虚继承时:每个含有虚函数的表只有一个虚函数表,所以只需要一个虚表指针即可;
当多继承且非虚继承时:一个子类有几个父类则会有几个虚函数表,所以就有和父类个数相同的虚表指针来标识;
总之,当时非虚继承时,不需要额外增加虚函数表指针。
当虚继承时:无论是单虚继承还是多虚继承,需要有一个虚基类表来记录虚继承关系,所以此时子类需要多一个虚基类表指针;而且只需要一个即可。
当虚继承时可能出现一个类中持有多个虚函数表的情况:无论是单虚继承还是多虚继承,
如果子类没有构造函数和析构函数,且子类中的虚函数都是在父类中出现的虚函数,这个时候不需要增加任何虚表指针;只需要像多继承那个持有父类个数的虚表指针来标识即可;
如果子类中含有构造函数或者析构函数或二者都有,则在子类中只要每出现一个父类中的虚函数则需要增加一个虚函数表指针来标识此类的虚函数表;
无论是否含有构造函数或者虚构函数,只要继承都是虚继承且出现了父类中没有出现的虚函数,则在子类中需要再增加一个徐函数表指针;如果其中有一个是非虚继承,则按照最省空间的原则,不需要增加虚函数表指针,因为这个时候可以和非虚基类共享一个虚函数表指针。
C++中虚基类在派生类中的内存布局的更多相关文章
- 详解C++中基类与派生类的转换以及虚基类
很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...
- (转) C++中基类和派生类之间的同名函数的重载问题
下面有关派生类与基类中存在同名函数 fn: class A { public: void fn() {} void fn(int a) {} }; class B : public A { publi ...
- C++基类、派生类、虚函数的几个知识点
1.尽管派生类中含有基类继承来的成员,但派生类初始化这部分变量需要调用基类的构造函数. class A { private: int x; virtual void f(){cout<<& ...
- c++中基类与派生类中隐含的this指针的分析
先不要看结果,看一下你是否真正了解了this指针? #include<iostream> using namespace std; class Parent{ public: int x; ...
- c++ 的类 和 类继承, 什么是c++中的基类和派生类?
闲云潭影日悠悠,物换星移几度秋 你既然已经做出了选择, 又何必去问为什么选择.鬼谷绝学的要义, 从来都不是回答, 而是抉与择 普通类 #ifndef TABTENN0_H_ #define TABTE ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- C++基类和派生类之间的转换
本文讲解内容的前提是派生类继承基类的方式是公有继承,关键字public 以下程序为讲解用例. #include<iostream> using namespace std; class A ...
- OOP1(定义基类和派生类)
面向对象程序设计基于三个基本概念:数据抽象,继承和动态绑定 数据抽象是一种依赖于接口和实现分离的编程技术.继承和动态绑定对程序的编号有两方面的影响:一是我们可以更容易地定义与其它类相似但不完全相同的类 ...
- C++学习21 基类和派生类的赋值
在C/C++中,经常会发生数据类型转换,例如整型数据可以赋值给浮点型变量,在赋值之前,先把整型数据转换为浮点型:反过来,浮点型数据也可以赋值给整型变量. 数据类型转换的前提是,编译器知道如何对数据进行 ...
- 基类和派生类--this
基类指针在程序运行的时候的确指向的是一个派生类的对象,但指针的类型仍然是基类指针.C++是一种强类型语言,因此不能用基类指针类型的指针直接调用派生类:而且,同一个类可能有多种不同的派生类,因此不知道实 ...
随机推荐
- iOS强引用和弱引用
保留一个对象创建了一个对该对象的“强”引用.一个对象只有在它的所有强引用都被释放后才能被回收.因此,一个对象的生命周期取决于其强引用的所有者.在某些情况下,这种行为可能并不理想.您可能想要引用一个对象 ...
- Windows下安装配置SBT
1:安装包下载界面 http://www.scala-sbt.org/download.html 下载后进行安装. 安装路径:D:\Java\sbt\conf 2:进行配置 (1)sbtconfig. ...
- 如何设置mysql登陆密码?
此情况用于mysql密码为空. 命令如下: Mysqladmin –uroot password root1234 Root是用户名,root1234是新设置的密码
- JAVA 爬虫Gecco
主要代码: Gecco(matchUrl="https://github.com/{user}/{project}", pipelines="consolePipelin ...
- Java 提示“找不到或无法加载主类” 解决方法
1.检查环境变量配置,我的安装路径是F:\java\jdk1.8.0_91,因为是6以上版本,故不需配置Classpath 否则 CLASSPATH=.;%JAVA_HOME%\lib\dt.jar; ...
- win7 登录后只能使用“临时配置文件”,原来的配置文件无法启用!
这个问题,修改注册表就可以解决. 开始-> 运行-> 输入regedit,回车, 在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Cur ...
- win7,8,10取得|取消管理员权限
取得: Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\*\shell\runas]@=”管理员取得所有权”“NoWorkingDirec ...
- 使用JDK自带的JAXB进行类和xml的互转
Classroom.java public class Classroom { private int id; private String name; private int grade; publ ...
- 16、java包装类
一.包装类的由来: JAVA是面向对象的编程语言,但它也包含了8种基本数据类型,这8个基本数据类型不支持面向对象的编程机制,基本数据类型的数据也不具备“对象”的特性:没有属性,方法可以被调用.JAVA ...
- Loadrunner脚本编程(1)-大体思路
http://www.360doc.com/content/10/0806/13/1698198_44076570.shtml 就目前的了解.Loadrunner的脚本语言其实和C没什么区别.他内部的 ...