C++中virtual继承的深入理解
今天专门看了一下虚继承的东西,以前都没怎么用过,具体如下:
父类:
{
....
};
继承类的声明比较特别:
class CChild : virtual public CParent
{
....
}
请问,这个"virtual"是什么作用及含义?
---------------------------------------------------------------
表示虚拟继承,和普通继承是C++的两种继承方式。
例如B1、B2 继承A 而C多重继承B1、B2
如果普通继承则C包含两份A的拷贝,分别来自于B1、B2
而虚拟继承则只包含一份A的拷贝
---------------------------------------------------------------
这个"virtual"是什么作用及含义?
证明这个CParent是CChild 的虚基类
虚基类 的 作用
虚基类是指:class SubClass : virtual public BaseClass 中以virtual声明的基类!!由于C++支持多重继承,所以对于一个派生类中有几个直接父类,而几个直接父类中有几个可能分别继承自某一个基类(就是父类的父类),这样在构造最终派生类时,会出现最终派生类中含有多个同一个基类的情况,就会产生二义性的问题(不知道该调用哪个基类的成员变量和函数),为解决此问题,需要使用虚基类,即只对此基类生成一块内存区域,这样最终派生类中就只会含有一个基类了
典型的需要用虚基类的情况如下:
A
/ \
B C
\ /
D
其中D继承自BC,BC分别继承自A,所以A要分别被BC虚拟继承
程序嘛…………
public:
void printA() {cout<<"this is A\n";}
};
class B:virtual public A;
class C:virtual public A;
class D:public B,public C;
这样在D构造出来后,它的存储区域中只有一个A,不会有二义性问题
比如:D d=new D;
此时若使用d.printA();不会有问题;但若B和C不是虚继承自A,就会有二义性问题
COM中 多重继承不采用虚拟继承, 否则会导致与COM不兼容的vtbl。若 IX 和 IY 按照虚拟继承方式继承IUnknown,那么 IX 和 IY 的vtbl中的头三个函数指向的将不是IUnknown的三个成员函数(详见Com技术内幕)
IUnknown -> IX
---> CA
IUnknown -> IY
通常将一种类型的指针转换成另外一种类型的指针并不会改变指针的值,但为了支持多重继承,在某些情况下,C++必须改变类指针的值。COM中的多接口继承就是如此,此时
CA* pA = new CA();
IY * pc = pA; 会被编译器改成 IY * pC = (char * )pA + deltaIY(一个偏移量);
基类的析构函数也应该定义成virtual才会在继承类的实例析构时被调用以清除基类用到的资源。
C++中virtual继承的深入理解的更多相关文章
- 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承
ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...
- Java中的继承、封装、多态的理解
Java中的继承.封装.多态 继承的理解: 1.继承是面向对象的三大特征之一,也是实现代码复用的重要手段.Java的继承具有单继承的特点,每个子类只有一个直接父类. 2.Java的继承通过extend ...
- 带你理解【JavaScript】中的继承机制
前文 总所周知,继承是所有OO语言中都拥有的一个共性.在JavaScript中,它的继承机制与其他OO语言有着很大的不同,尽管ES6为我们提供了像面向对象继承一样的语法糖,但是其底层依然是构造函数,所 ...
- 深入理解JavaScript中的继承
1前言 继承是JavaScript中的重要概念,可以说要学好JavaScript,必须搞清楚JavaScript中的继承.我最开始是通过看视频听培训班的老师讲解的JavaScript中的继承,当时看的 ...
- C++反汇编第四讲,反汇编中识别继承关系,父类,子类,成员对象
C++反汇编第四讲,反汇编中识别继承关系,父类,子类,成员对象 讲解目录: 1.各类在内存中的表现形式 备注: 主要复习开发知识,和反汇编没有关系,但是是理解反汇编的前提. 2.子类继承父 ...
- C++ virtual继承
C++ virtual继承的还有一种名称是菱形继承.主要目的是用于解决从不同类继承来的同名数据成员在内存中有不同的拷贝.造成数据不统一的问题,以致于在进行类释放时造成内存泄漏. 将共同的基类作为虚基类 ...
- C#中对IDisposable接口的理解
http://blog.sina.com.cn/s/blog_8abeac5b01019u19.html C#中对IDisposable接口的理解 本人最近接触一个项目,在这个项目里面看到很多类实现了 ...
- C#中的继承
按照我个人的理解,继承和实现接口不是一个概念,结构和类型都可以实现接口,枚举不能. 话说,结构可以继承吗? 先梳理一下C#中的继承关系,如下图: class => [BaseClass => ...
- JavaScript中的继承(原型链)
一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.pro ...
随机推荐
- Redis实现分布式锁(Set和Lua)
转载:https://www.cnblogs.com/linjiqin/p/8003838.html 前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于Z ...
- easyUI datagrid组件能否有display:none的隐藏效果
这个项目用了JQ easyUI datagrid 组件,我今天做了一个页面,页面有个div层,div里放了一个easyUI datagrid,页面初始化时div隐藏(display:none),通过点 ...
- Spring中的AOP(学习笔记)
是什么AOP及实现方式 AOP的基本概念 Schema-base AOP Spring AOP API AspectJ
- Mysql常见函数
一.单行函数 1.字符函数 concat拼接 substr截取子串 upper转换成大写 lower转换成小写 trim去前后指定的空格和字符 ltrim去左边空格 rtrim去右边空格 replac ...
- js遍历map
//火狐控制台打印输出: Object { fileNumber="文件编号", fileName="文件名称"} console.log(map); for( ...
- django-sso单点登陆的实现
环境准备 环境规格: python3.5 django2.0 django-simple-sso-0.14 环境安装: pip install django-simple-sso-0.14 环境说明: ...
- vue弹窗插件实战
vue做移动端经常碰到弹窗的需求, 这里写一个功能简单的vue弹窗 popup.vue <template> <div class="popup-wrapper" ...
- react native 知识点总结(一)
一.关于react native 版本的升级 参照文档:http://reactnative.cn/docs/0.45/upgrading.html react-native -v 查看当前版本 ...
- 适配器、工厂模式、线程池、线程组、互斥锁、Timer类、Runtime类、单例设计模式(二十四)
1.多线程方法 * Thread 里面的俩个方法* 1.yield让出CPU,又称为礼让线程* 2.setPriority()设置线程的优先级 * 优先级最大是10,Thread.MAX_PRIORI ...
- lucene Index Store TermVector 说明
最新的lucene 3.0的field是这样的: Field options for indexingIndex.ANALYZED – use the analyzer to break the Fi ...