请教一下C++类的继承(虚继承和多继承)导致Class内存变化的问题
请教一下C++类的继承(虚继承和多继承)导致内存变化的问题:
class Class_Base
{
private:
int base_data;
public:
void f1() {cout << "\nLet's find the mean.\n";}
void f2() {cout << "\nLet's find the median.\n";}
virtual void f3() {cout << "\nLet's find the mode.\n";}
};
class Class_E: virtual/public Class_Base
{
private:
int derived_data1;
public:
void f4() {cout << "\nLet's find the variance.\n";}
void f5() {cout << "\nLet's find the deviation.\n";}
};
class Class_F: virtual/public Class_Base
{
private:
int derived_data2;
public:
void f4() {cout << "\nLet's find the variance.\n";}
virtual void f6() {cout << "\nLet's find the standard deviation.\n";}
};
class Class_GG: public Class_E, public Class_F
{
public:
void functions()
{
Class_E :: f4();
f5();
Class_F :: f4();
f6();
}
};
int main()
{
printf("\nThe size of the base class is %d.", sizeof(Class_Base));
printf("\nThe size of the 1st derived class is %d.", sizeof(Class_E));
printf("\nThe size of the 2nd derived class is %d.", sizeof(Class_F));
printf("\nThe size of the derived-derived class is %d.", sizeof(Class_GG));
return 0;
}
经过我的实验,
- 如果Base所有函数都是void(包括f3)没有virtual,那么派生Class_E的大小是8。
- 如果只要有一个Base函数(比如f3)是virtual,或者派生Class_E的继承本身是virtual,那么派生Class_E的大小是16。
- 如果既有Base虚函数(比如f3)、又有虚继承,那么派生Class_E的大小是32。
所以,请问:为什么是8、16、32这样的大小呢?
另外,如果Class_E和Class_F从Class_Base派生时都是虚继承virtual而不是public继承,那么在Class_GG里,本来应该可以避免Class_E和Class_F都有一个叫f4()的函数的命名冲突。但是我又试了一下,先把Class_E和Class_F都改成从Class_Base的虚继承,再在Class_GG里这样写
class Class_GG: Class_E, Class_F // 或者public Class_E, public Class_F // 或者virtual Class_E, vitual Class_F
{
public:
void functions()
{
f4();
f5();
f6();
}
};
然而编译时却无法通过。请问:到底应该怎么解决这种多继承里函数命名的冲突呢? functions()到底又是什么呢?
谢谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果了解了C++内存对象模型,就可以解释这些行为。
主要有两点:virtual函数依靠vptr,在运行时确定实际函数;virtual继承的积累在整个继承体系中共享一个积累对象。
以下根据Linux中使用g++编译器实现的内存模型进行分析。
如果Base所有函数都是void(包括f3)没有virtual,那么派生Class_E的大小是8。
如果只要有一个Base函数(比如f3)是virtual,那么派生Class_E的大小是16。
如果派生Class_E的继承本身是virtual,那么派生Class_E的大小是16。
4.如果既有Base虚函数(比如f3)、又有虚继承,那么派生Class_E的大小是32。
参考:《深度探索C++内存对象模型》