C++(笔记)浅析菱形继承&虚继承底层内存占用
来源:互联网 发布:大数据交易中心 编辑:程序博客网 时间:2024/06/05 14:40
一、什么是菱形继承
二、代码实现
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>#include <math.h>#include <cmath>#include <iostream>using namespace std;class A{public: void run() { cout<<"A running"<<endl; }private: int a;};class B:public A{private: int b;};class C:public A{private: int c;};class D:public B,public C{private: int d;};int main(){ D d; d.run(); return 0;}
以上代码编译的时候是报错的,报错结果为run函数是不确定的
导致run不确定的原因是:D的对象模型里面保存了两份A,当我们想要调用A里继承的run时就会调用不明确,并造成数据冗余问题(明明只要一份就好,我们却保存了两份)
解决方法
1.使用作用域(不建议)
只需在主函数中改变
int main(){ D d; d.B::run(); d.C::run(); return 0;}
2.使用虚继承(建议)
虚继承即让B和C在继承A时加上virtual关键字,记住不是D虚继承
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>#include <math.h>#include <cmath>#include <iostream>using namespace std;class A{public: void run() { cout<<"A running"<<endl; }private: int a;};class B:virtual public A{private: int b;};class C:virtual public A{private: int c;};class D:public B,public C{private: int d;};int main(){ D d; d.run(); return 0;}
三、解析虚继承原理
TDM-GCC 4.9.2 64-bit Release下编译(不同环境下所占大小不同)
1、普通继承下占用内存(字节)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>#include <math.h>#include <cmath>#include <iostream>using namespace std;class A{public: void run() { cout<<"A running"<<endl; }private: int a;};class B:public A{private: int b; };class C:public A{private: int c;};class D:public B,public C{private: int d;};int main(){ cout<<"A="<<sizeof(A)<<endl;//A=4 cout<<"B="<<sizeof(B)<<endl;//B=8 cout<<"C="<<sizeof(C)<<endl;//C=8 cout<<"D="<<sizeof(D)<<endl;//D=20 return 0;}
如果A没有int a那么A占1个字节(这一个字节是A类本身所占用的)
2、虚继承下占用内存
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>#include <math.h>#include <cmath>#include <iostream>using namespace std;class A{public: void run() { cout<<"A running"<<endl; }private: int a;};class B:virtual public A{private: int b; };class C:virtual public A{private: int c;};class D:public B,public C{private: int d;};int main(){ cout<<"A="<<sizeof(A)<<endl;//A=4 cout<<"B="<<sizeof(B)<<endl;//B=16 cout<<"C="<<sizeof(C)<<endl;//C=16 cout<<"D="<<sizeof(D)<<endl;//D=40 return 0;}
B和C从8字节变成了16字节,是因为包含了一个指向虚表指针占8字节
而D从20字节变成了40字节,是包括A(4),B/C(16),本身(4)
1 0
- C++(笔记)浅析菱形继承&虚继承底层内存占用
- 【C++】菱形虚拟继承(内存布局)
- 【C++】c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- 【C++】c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- 【C++】继承(菱形继承)
- 菱形继承浅析
- 继承(单继承、多继承、菱形继承、虚继承)
- 菱形继承 虚继承
- (C++)继承、菱形继承和虚继承的那些事儿
- <c++>继承及菱形继承
- c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- c++单继承、多继承、菱形继承的内存布局(虚函数表结构)
- 【C++】菱形继承
- 【c++】菱形继承
- 【c++】菱形继承
- C++(虚)继承类的内存占用大小
- C++(虚)继承类的内存占用大小
- c++:继承相关的要点热点,以及菱形继承的底层实现
- hibernate配置文件hibernate.cfg.xml的详细解释
- error in invokeing target 'mkldflags ntcontab.o' of makefile
- 主线程 子线程 同步请求 异步请求
- Glide-源码详解
- eLockViolation异常处理方法
- C++(笔记)浅析菱形继承&虚继承底层内存占用
- 从 NSObject 的初始化了解 isa
- [Leetcode] 132. Palindrome Partitioning II 解题报告
- webApp书城开发学习笔记
- Netty入门应用
- hdu1022(stack)
- SharedPreference的应用
- SQL语句自动生成封装---数据实体操作封装(二)
- Java开发代码性能优化总结