[C++基础]虚继承实现原理
在C++中,我们会遇到virtual这个关键字,但是它有两种含义:虚函数和虚继承,它们两个是完全无相关的两个概念。
什么是虚继承
虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。
当一个基类被声明为虚基类后,即使它成为了多继承链路上的公共基类,最后的派生类中也只有它的一个备份。例如:
class CBase { };
class CDerive1:virtual public CBase{ };
class CDerive2:virtual public CBase{ };
class CDerive12:public CDerive1,CDerive2{ };
则在类CDerive12的对象中,仅有类CBase的一个对象数据
虚继承实现原理
虚继承底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(任何类型的指针变量都是占用4个字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。
实际上,vbptr指的是虚基类表指针,该指针指向了一个虚基类表,虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间。
虚继承与虚函数的异同
相似之处:都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间)。
不同之处:虚基类依旧存在继承类中,只占用存储空间;虚函数不占用存储空间。虚基类表存储的是虚基类相对直接继承类的偏移;而虚函数表存储的是虚函数地址。
#include<iostream>
using namespace std;class A //大小为4
{
public:int a;
};
class B :virtual public A //大小为12,变量a,b共8字节,虚基类表指针4
{
public:int b;
};
class C :virtual public A //与B一样12
{
public:int c;
};
class D :public B, public C //24,变量a,b,c,d共16,B的虚基类指针4,C的虚基类指针
{
public:int d;
};int main()
{A a;B b;C c;D d;cout << sizeof(a) << endl;cout << sizeof(b) << endl;cout << sizeof(c) << endl;cout << sizeof(d) << endl;system("pause");return 0;
}
//
//1 > class A size(4) :
//1 > +-- -
//1 > 0 | a
//1 > +-- -
//1 >
//1 > class B size(12) :
//1 > +-- -
//1 > 0 | {vbptr}
//1 > 4 | b
//1 > +-- -
//1 > +-- - (virtual base A)
//1 > 8 | a
//1 > +-- -
//1 >
//1 > B::$vbtable@:
//1 > 0 | 0
//1 > 1 | 8 (Bd(B + 0)A)
//1 > vbi:class offset o.vbptr o.vbte fVtorDisp
//1 > A 8 0 4 0
//1 >
//1 > class C size(12) :
//1 > +-- -
//1 > 0 | {vbptr}
//1 > 4 | c
//1 > +-- -
//1 > +-- - (virtual base A)
//1 > 8 | a
//1 > +-- -
//1 >
//1 > C::$vbtable@:
//1 > 0 | 0
//1 > 1 | 8 (Cd(C + 0)A)
//1 > vbi:class offset o.vbptr o.vbte fVtorDisp
//1 > A 8 0 4 0
//1 >
//1 > class D size(24) :
//1 > +-- -
//1 > 0 | +-- - (base class B)
//1 > 0 | | {vbptr}
//1 > 4 | | b
//1 > | +-- -
//1 > 8 | +-- - (base class C)
//1 > 8 | | {vbptr}
//1 > 12 | | c
//1 > | +-- -
//1 > 16 | d
//1 > +-- -
//1 > +-- - (virtual base A)
//1 > 20 | a
//1 > +-- -
//1 >
//1 > D::$vbtable@B@:
//1 > 0 | 0
//1 > 1 | 20 (Dd(B + 0)A)
//1 >
//1 > D::$vbtable@C@:
//1 > 0 | 0
//1 > 1 | 12 (Dd(C + 0)A)
//1 > vbi:class offset o.vbptr o.vbte fVtorDisp
//1 > A 20 0 4 0
//1 >
[C++基础]虚继承实现原理相关推荐
- 继承详解(虚继承实现原理)
继承的概念及定义 概念: 继承机制是面向对象程序设计为了提高代码复用率的一种手段,它可以保持原类特性的基础上进行拓展,简单来说继承是类层次的复用. 接下来我们来看一个简单的继承 class Per ...
- 多重继承与虚继承编程实验
多重继承与虚继承编程实验 基本知识 多重继承 多重继承下的类作用域 虚继承 构造函数与虚继承 关于本程序 示例代码 Animal_virtual_baseVers.h virt-inherit.cpp ...
- C++虚继承中的虚基类表
虚继承主要解决多重继承会在子类中存在多份拷贝的问题,这不仅浪费空间,而且存在二义性. 在之前的 C++ 继承中已经说过虚继承基本概念,这里不再赘述.这篇文章主要探究虚继承的原理.文章中多处给出了类实例 ...
- C++虚继承与虚函数
虚继承和虚函数是完全无相关的两个概念. 虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝.这将存在两个问题:其一,浪费存储空间:第二,存在二义性问题,通常可 ...
- 菱形继承,多继承,虚继承、虚表的内存结构全面剖析(逆向分析基础)
// 声明:以下代码均在Win32_Sp3 VC6.0_DEBUG版中调试通过.. 在逆向还原代码的时候,必须得掌握了菱形继承,多继承,虚继承虚函数的内存虚表结构.所以,这篇文章献给正在学习C++ ...
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7883531 一.虚函数的工作原理 虚函数的实现要求对象携带额 ...
- C++虚继承中构造函数和析构函数顺序问题以及原理
多重继承的问题:多个类B,C,-继承同一个类A导致如果X继承了B,C,-那么在X中将还有多个A中成员的拷贝,如果想要访问A中的成员如果不加名字空间将会导致二义性,这种拷贝大多是没有实际意义的,为了避免 ...
- C++虚继承的实现原理、内存分布、作用
虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝.这将存在两个问题:其一,浪费存储空间:第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现 ...
- C++继承机制(三)——多继承、菱形继承、虚继承原理
目录: C++继承机制(一)--基本语法.三种继承方式.继承哪些数据 C++继承机制(二)--继承中的构造和析构顺序.继承同名成员的处理方式 C++继承机制(三)--多继承.菱形继承.虚继承原理 本篇 ...
最新文章
- 何凯明团队又出新论文!北大、上交校友教你用ViT做迁移学习
- 时间序列数据的存储和计算 - 开源时序数据库解析
- 【数据竞赛】Kaggle秘技,用Sigmoid函数做回归问题!
- armbian安装图形桌面_Linux图形界面的搜索工具,比Windows强吗?
- Nginx的http块自定义服务日志
- 坚持做一件事情真的很不容易,首先必须要克服惰性!
- lass翻译_【专题讲座】政务翻译人才培训系列讲座(1)
- resolv.conf
- 我是如何使用wireshark软件的
- (算法)宝石升级问题
- 如何在开源社区贡献代码_在社区支持大量涌现之后,Biicode便开始开源
- 贾跃亭“站台”!乐视高调宣布回归:60余款新品发布,还将发布超级手机
- python scrapy框架 抓取的图片路径打不开图片_Python中Scrapy爬虫图片处理详解
- 迷你MVVM框架 avalonjs 学习教程6、插入移除处理
- 如何使用Python开发随机森林集成
- 李商隐和杜牧并称“小李杜”,他俩到底谁的成就高?
- 花在照顾子女上的时间对父亲自己的大脑具有可塑性?
- 屏蔽去除CSDN上图片轮播形式的百度推广广告-20190104更新
- 在Mac M1芯片下使用Android Studio模拟器
- 女巫的魔法-第12届蓝桥杯Scratch省赛3真题第2题