多继承(虚继承)派生类对象内存结构
来源:互联网 发布:mac开机一个问号 编辑:程序博客网 时间:2024/06/08 05:21
在这里谈一下虚继承。前面写过派生类对象的内存结构,都是基于VS2010编译器的,不同的编译器对于继承的处理不同,但本质都是一样的。
虚继承是解决共享基类问题的。例如在菱形继承中
如果不使用虚继承,基类A在D中会有两个,这不仅浪费内存,还会造成歧义。使用虚继承就可以解决基类共享的问题。
要想在派生类中共享基类(例如在D对象中只有一个A对象,这时候D对象中的B对象和C对象都可以查找到A,而不是在B对象和C对象中各含有一个A对象)。
先看下面一个例子:
#include<iostream>using namespace std;class A{public:A():a(10){};int a;};class B: public virtual A{public:B():b(20){};int b;};class C:public virtual A{public:C():c(30){};int c;};class D:public B, public C{public:D():d(40){};int d;};int main(){cout<<"A size is "<<sizeof(A)<<endl;cout<<"B size is "<<sizeof(B)<<endl;cout<<"C size is "<<sizeof(C)<<endl;cout<<"D size is "<<sizeof(D)<<endl;return 0;}VS2010运行结果如下:
A size is 4
B size is 12
C size is 12
D size is 24
之前在网上看过一些文章,解决虚继承共享对象的一个方案就是在虚函数表中添加共享对象的相对偏移。我们把D类对象各个部分打印出来看一下:
D d;int **p=(int **)&d;cout<<"以4字节为单位,分成5部分:"<<endl;for(int i=0; i<6; i++)cout<<"第"<<i<<"个部分的值"<<p[i]<<endl;
以4字节为单位,分成5部分:
第0个部分的值013078B0
第1个部分的值00000014
第2个部分的值013078A4
第3个部分的值0000001E
第4个部分的值00000028
第5个部分的值0000000A
可以看出第0部分和第2部分不是成员变量,其实是虚函数表指针,在虚函数表中记录着第5部分(就是虚基类A对象)相对其他对象的偏移。第0部分记录着相对对象B和相对对象D的偏移(可以看出偏移20个字节),第2部分记录着相对C对象的偏移(偏移12个字节),可以查看一下:
cout<<p[0][1]<<endl;cout<<p[2][1]<<endl;输出的结果就是20和12。
至于为什么在虚函数表的第一个位置,我还没搞懂,不过我想应该是不同的编译器有不同的安排,但是它们的目的都是共享虚基类A对象。
在D中查找虚基类,首先找到虚函数表,然后找到偏移的大小,之后才能找到虚基类对象,可见虚基类降低了效率。
0 0
- 多继承(虚继承)派生类对象内存结构
- 多继承(非虚继承)派生类对象内存结构(基类有虚函数)
- 虚函数: 多重继承下派生类对象的内存结构
- C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)
- c++对象多继承的内存结构
- C++对象内存布局:单继承,多继承,虚继承
- 继承:单继承、派生类成员的访问属性、多继承、菱形继承、虚继承,菱形虚拟继承
- 【C++】c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- c++单继承、多继承、菱形继承的内存布局(虚函数表结构)
- 【C++】c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- 含有虚函数多重继承派生类内存布局
- C++ 继承派生类中的内存布局
- 派生类析构函数举例(多继承、含有嵌入对象)
- 继承---派生类(C++)
- C++类、对象、继承、派生类基础教程
- 继承与派生(面向对象)
- 面向对象--多继承&派生类对象内存布局分析&各基类指针所指向的位置分析
- 并发编程--合并任务的结果
- 安装jdk8 for Linux
- 计算机图形学和OpenGL(二)坐标系和绘制点线函数
- function类型
- BZOJ 2763 JLOI2011 飞行路线 分层图+堆优化SPFA
- 多继承(虚继承)派生类对象内存结构
- 关于傅里叶的一些东西(整理)
- response通过writer输出数据
- PHP微信公众开发笔记(五)
- 设计模式之-观察者模式(Observer Design Pattern)
- STM32学习笔记——流水灯
- 笔记12 继承extends
- poj 1001(高精度)
- javascript的系统函数