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

虚继承和虚函数对c++对象存储模型的影响(类/对象的大小)

2017-03-02 21:43 330 查看
首先重新回顾一下关于类/对象大小的计算原则:

类大小计算遵循结构体对齐原则

类的大小与数据成员有关与成员函数无关

类的大小与静态数据成员无关

虚继承对类的大小的影响

虚函数对类的大小的影响

在g++编译器下的情况

一、只出现虚继承的情况

#include <iostream>
using namespace std;

class BB
{
public :
int bb_ ;
};

class B1 : virtual public BB
{
public :
int b1_ ;
};

class B2 : virtual public BB
{
public :
int b2_ ;
};

class DD : public B1, public B2
{
public :
int dd_ ;
};

int main (void)
{
cout<<sizeof (BB)<< endl;
cout<<sizeof (B1)<< endl;
cout<<sizeof (DD)<< endl;

return 0;


从输出的地址和虚基类表成员数据可以画出对象内存模型图:

virtual base table

本类地址与虚基类表指针地址的差

虚基类地址与虚基类表指针地址的差

virtual base table pointer(vbptr)



从程序可以看出pp是BB* 指针,通过打印pp 的值与&dd 比较可知,

cout<<(void*)&dd<

#include <iostream>
using namespace std;

class BB
{
public:
virtual void vpbb()
{
cout << "BB:vpbb().." << endl;
}
int bb_;
};
class B1 : public BB
{
public:
virtual void vpb1()
{
cout << "B1:vpb1().." << endl;
}
int b1_;
};
class B2 : public BB
{
public:
virtual void vpb2()
{
cout << "B2:vpb2().." << endl;
}
int b2_;
};
class DD : public B1, public B2
{
public:
virtual void vpdd()
{
cout << "DD:vpdd().." << endl;
}
int dd_;
};

typedef void (* FUNC)(void );

int main()
{
cout << sizeof(BB) << endl;
cout << sizeof(B1) << endl;
cout << sizeof(DD) << endl;
cout << endl;

return 0;
}


从成员输出的地址和通过虚函数表指针访问到的函数可以画出模型:



DD::vfdd 的位置跟继承的顺序有关,如果DD先继承的是B2, 那么它将跟在B2::vfb2 的下面。

如果派生类是从多个基类继承或者有多个继承分支(从所有根类开始算起),而其中若干个继承分支上出现了多态类,则派生类将从这些分支中的每个分支上继承一个vptr,编译器也将为它生成多个vtable,有几个vptr就生成几个vtable(每个vptr分别指向其中一个),分别与它的多态基类对应。

三、虚继承与虚函数同时出现的情况:

#include <iostream>
using namespace std;

class BB
{
public :
virtual void vfbb()
{
cout<<"BB::vfbb" <<endl;
}
virtual void vfbb2()
{
cout<<"BB::vfbb2" <<endl;
}
int bb_ ;
};

class B1 : virtual public BB
{
public :
virtual void vfb1()
{
cout<<"B1::vfb1" <<endl;
}
int b1_ ;
};

class B2 : virtual public BB
{
public :
virtual void vfb2()
{
cout<<"B2::vfb2" <<endl;
}
int b2_ ;
};

class DD : public B1, public B2
{
public :
virtual void vfdd()
{
cout<<"DD::vfdd" <<endl;
}
int dd_ ;
};

typedef void (* FUNC)(void);

int main (void)
{
cout<<sizeof (BB)<< endl;
cout<<sizeof (B1)<< endl;
cout<<sizeof (DD)<< endl;

return 0;
}


对象内存模型图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  虚继承-虚函数