#include<iostream>
using namespace std;
class class1
{
public:
int a;
double aa;
virtual void f(){}
};
class class2:virtual public class1
{
public :
int b;
char bb;
};
class class3:virtual public class1
{
public:
int d;
double dd;
};
class class4: public class2, public class3
{
public:
int e;
double ee;
};
int main()
{
cout<<"class1 ="<<sizeof(class1)<<endl;
cout<<"class2="<<sizeof(class2)<<endl;
cout<<"class3="<<sizeof(class3)<<endl;
cout<<"class4="<<sizeof(class4)<<endl;
getchar();
return 0;
}
1.虚继承
class class1 size(24):
1> +---
1> 0 | {vfptr}
1> 8 | a
1> | <alignment member> (size=4)
1>16 | aa
class class2 size(40):
1> +---
1> 0 | {vbptr}
1> 4 | b
1> 8 | bb
1> | <alignment member> (size=3)
1> | <alignment member> (size=4)
1> +---
1> +--- (virtual base class1)
1>16 | {vfptr}
1>24 | a
1> | <alignment member> (size=4)
1>32 | aa
class class3 size(48):
1> +---
1> 0 | {vbptr}
1> 8 | d
1> | <alignment member> (size=4)
1>16 | dd
1> +---
1> +--- (virtual base class1)
1>24 | {vfptr}
1>32 | a
1> | <alignment member> (size=4)
1>40 | aa
class class4 size(80):
1> +---
1> | +--- (base class class2)
1> 0 | | {vbptr}
1> 4 | | b
1> 8 | | bb
1> | | <alignment member> (size=3)
1> | | <alignment member> (size=4)
1> | +---
1> | +--- (base class class3)
1>16 | | {vbptr}
1>24 | | d
1> | | <alignment member> (size=4)
1>32 | | dd
1> | +---
1>40 | e
1> | <alignment member> (size=4)
1>48 | ee
1> +---
1> +--- (virtual base class1)
1>56 | {vfptr}
1>64 | a
1> | <alignment member> (size=4)
1>72 | aa
#include<iostream>
using namespace std;
class class1
{
public:
int a;
double aa;
virtual void f(){}
};
class class2: public class1
{
public :
int b;
char bb;
};
class class3: public class1
{
public:
int d;
double dd;
};
class class4: public class2, public class3
{
public:
int e;
double ee;
};
int main()
{
cout<<"class1 ="<<sizeof(class1)<<endl;
cout<<"class2="<<sizeof(class2)<<endl;
cout<<"class3="<<sizeof(class3)<<endl;
cout<<"class4="<<sizeof(class4)<<endl;
getchar();
return 0;}
直接继承(注意多重继承class4可能出现错误)
class class1 size(24):
1> +---
1> 0 | {vfptr}
1> 8 | a
1> | <alignment member> (size=4)
1>16 | aa
class class2 size(32):
1> +---
1> | +--- (base class class1)
1> 0 | | {vfptr}
1> 8 | | a
1> | | <alignment member> (size=4)
1>16 | | aa
1> | +---
1>24 | b
1>28 | bb
class class3 size(40):
1> +---
1> | +--- (base class class1)
1> 0 | | {vfptr}
1> 8 | | a
1> | | <alignment member> (size=4)
1>16 | | aa
1> | +---
1>24 | d
1> | <alignment member> (size=4)
1>32 | dd
class class4 size(88):
1> +---
1> | +--- (base class class2)
1> | | +--- (base class class1)
1> 0 | | | {vfptr}
1> 8 | | | a
1> | | | <alignment member> (size=4)
1>16 | | | aa
1> | | +---
1>24 | | b
1>28 | | bb
1> | | <alignment member> (size=3)
1> | +---
1> | +--- (base class class3)
1> | | +--- (base class class1)
1>32 | | | {vfptr}
1>40 | | | a
1> | | | <alignment member> (size=4)
1>48 | | | aa
1> | | +---
1>56 | | d
1> | | <alignment member> (size=4)
1>64 | | dd
1> | +---
1>72 | e
1> | <alignment member> (size=4)
1>80 | ee
分析:
虚函数实现晚绑定,所以虚继承时派生类class2中的变量顺序是虚基类指针,类变量,而后是基类内容。
注意:VC编译器中如果派生类class2中也有一个不同于基类的虚函数,则将会在虚基类指针前添加一个虚函数指针。
而gcc编译器则不会添加,将共享虚函数指针。
而如果不是虚继承则VC++也共享虚函数指针。
直接继承实现早绑定,所以派生类class2中,首先是基类的内容,而后才是派生类的内容。(注意结构对齐问题,若变量a处于最长变量之前,则a对齐到最长变量长度,而若变量b处于最长变量之后,则进行补足,如
Struct s1{
Int a;
Double b;
Int c;
Int d;
};
Size(s1)=24.)
多重继承若不采用虚继承,将产生多个基类,如class4产生了两个class1的副本。
类结构的查看可以通过在编译选项中加入/d1reportAllClassLayout