一、什么是菱形继承
二、代码实现
#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;
cout<<
"B="<<
sizeof(B)<<endl;
cout<<
"C="<<
sizeof(C)<<endl;
cout<<
"D="<<
sizeof(D)<<endl;
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;
cout<<
"B="<<
sizeof(B)<<endl;
cout<<
"C="<<
sizeof(C)<<endl;
cout<<
"D="<<
sizeof(D)<<endl;
return 0;
}
B和C从8字节变成了16字节,是因为包含了一个指向虚表指针占8字节 而D从20字节变成了40字节,是包括A(4),B/C(16),本身(4)