您的位置:首页 > 编程语言 > C语言/C++

C++多继承虚函数类内部模型结构剖析

2015-03-27 14:31 309 查看
这里主要看看C++在多继承含有虚函数的情况下类的内部成员结构和分布。

类继承体系代码如下,先看看非虚继承的情况:

class Base{
public:
Base(){}
virtual ~Base(){}
virtual void v(){}
void f(){}
public:
int data_Base;
};
class Base1 :  public Base{
public:
Base1(){}
virtual ~Base1(){}
virtual void v1(){}
void f1(){}
public:
int data_Base1;
};

class Base2 :  public Base{
public:
Base2(){}
virtual ~Base2(){}
virtual void v2(){}
void f2(){}
public:
int data_Base2;
};

class Derived : public Base1, public Base2 {
public:
Derived(){}
virtual ~Derived(){}
virtual void v(){}
virtual void v1(){}
virtual void v2(){}
virtual void v3(){}
void f3(){}
public:
int data_Derived;
};


使用VS2010提供的Command Prompt工具里的"cld1"命令查看类的结构如下:



由此可以看到,Derived类在内存里由低到高地址存储的分别是:

vfptr(虚函数表指针,包含Derived类新增的虚函数以及重写的或未重写的Base1基类的虚函数);

data_Base(Base基类的成员变量);

data_Base1(Base1基类的成员变量);

vfptr(虚函数表指针,包含Derived类重写的或未重写的Base2基类的虚函数);

data_Base(Base基类的成员变量);

data_Base2(Base2基类的成员变量);

data_Derived(Derived基类的成员变量);

总共28个字节,以下是测试代码:

int main(void)
{
Base1 base1;
Derived derived;
int *p1 = (int*)(&base1);
int *p2 = (int*)(&derived);
derived.data_Base1 = 3;
derived.data_Base2 = 4;
derived.Base1::data_Base = 1;
derived.Base2::data_Base = 2;
derived.data_Derived = 5;
for (int i = 0; i < 10; i++)
{
cout << hex <<p2<<":"<<hex<<*p2++ << endl;
}
cout << "derived size:" <<dec<< sizeof(derived) << endl;
int a = 0;
cin >> a;
return 0;
}


代码打印从Derived实例内存首地址开始的十个整形数据,结果如下:



与上面分析的一致,可以看出Derived包含了基类Base的两份数据,因此需要使用虚继承去掉公共基类的数据重复,加上虚继承后的类代码如下:

class Base{
public:
Base(){}
virtual ~Base(){}
virtual void v(){}
void f(){}
protected:
float data_Base;
};
class Base1 : virtual  public Base{
public:
Base1(){}
virtual ~Base1(){}
virtual void v1(){}
void f1(){}
protected:
float data_Base1;
};

class Base2 : virtual  public Base{
public:
Base2(){}
virtual ~Base2(){}
virtual void v2(){}
void f2(){}
protected:
float data_Base2;
};

class Derived : public Base1, public Base2 {
public:
Derived(){}
virtual ~Derived(){}
virtual void v(){}
virtual void v1(){}
virtual void v2(){}
virtual void v3(){}
void f3(){}
protected:
float data_Derived;
};


类结构分析结果如下:



由此可以看到,加上虚继承后Derived类在内存里由低到高地址存储的分别是:

vfptr(虚函数表指针,包含Derived类新增的虚函数以及重写的或为重写的Base1基类的虚函数);

vbptr(Base1基类指向公共基类成分部分的指针)

data_Base1(Base1基类的成员变量);

vfptr(虚函数表指针,包含Derived类重写的或未重写的Base2基类的虚函数);

vbptr(Base2基类指向公共基类成分部分的指针)

data_Base2(Base2基类的成员变量);

data_Derived(Derived基类的成员变量);
vtordip(C++虚继承机制历史遗留的成员,始终为0);

vbptr(虚函数表指针,包含Derived类重写的或未重写的Base基类的虚函数);

data_Base(Base公用基类的成员变量)

总共40个字节,以下是测试代码:

int main(void)
{
Base1 base1;
Derived derived;
int *p1 = (int*)(&base1);
int *p2 = (int*)(&derived);
derived.data_Base1 = 3;
derived.data_Base2 = 4;
derived.data_Base = 1;
derived.data_Derived = 5;
for (int i = 0; i < 10; i++)
{
cout << hex <<p2<<":"<<hex<<*p2++ << endl;
}
cout << "derived size:" <<dec<< sizeof(derived) << endl;
int a = 0;
cin >> a;
return 0;
}




OK,与上面分析的一致。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: