C++(笔记)浅析菱形继承&虚继承底层内存占用

xiaoxiao2021-02-27  552

一、什么是菱形继承

二、代码实现

#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)

转载请注明原文地址: https://www.6miu.com/read-1207.html

最新回复(0)