C++类对象大小的计算(二)含有虚函数类大小计算
2014-10-01 15:54
281 查看
前一篇文章《C++类对象大小的计算(一)常规类大小计算》初步介绍类大小计算后,我们继续来讨论含有虚函数时类的大小。
以下内存测试环境为Win7+VS2012,操作系统为32位
五、包含虚函数的类
包含虚函数的类,对象生成时,会在类对象当中插入一个指针,这个指针称做虚函数表指针,简称虚表指针(vPtr)。该指针指向一个虚函数表(简称虚表),虚函数表中存储了虚函数的入口地址。基类当中有虚函数时,会产生该虚函数表;创建基类对象,对象中的vPtr会指向该表;调用虚函数时,是通过vPtr在此表当中寻找函数入口地址的。
当派生类继承含有虚函数的子类时,会复制一份虚函数表,派生类如果有与基类中虚函数同名的虚函数,会在虚函数表中覆盖原来基类的虚函数;如果虚函数不重名,只会在虚函数表中增加一个函数入口。这种机制实现了类的多态。
如下面的例子:
VS类结构图:
运行结果为:
类A没有虚函数,因此大小仍然是1。类B因为有虚函数,其对象当中包含了一个vPtr指针,指针指向类B的虚函数表(假设为vTB),该表中存储了printB的入口地址,因此大小为4。类C因为继承了类B,也就复制了vTB(设为vTC),其对象中也就包含了指向vTC的虚表指针,该虚表中除了有printB的入口地址外,还包含了printC的入口地址,因此,类C对象大小为4。
考虑另一种情况,类C同时继承了类A、B,类A、B当中都有虚函数。如下面的例子:
VS类结构图:
运行结果为:
类A、B对象的大小按照上面所说的内存很好理解。类C因为同时继承了类A、B,因此就复制了两个虚函数表,也就有了两个vPtr,所以大小为8。如果类C有虚函数,也会放在其中一张虚函数表当中,不会再增加对象大小。
含有成员变量时,按照《C++类对象大小的计算(一)常规类大小计算》所讲内容加上相应的大小即可。
下面的文章《C++类对象大小的计算(三)含有虚函数、虚继承类大小计算》会讨论增加虚继承时,类对象的大小。
以下内存测试环境为Win7+VS2012,操作系统为32位
五、包含虚函数的类
包含虚函数的类,对象生成时,会在类对象当中插入一个指针,这个指针称做虚函数表指针,简称虚表指针(vPtr)。该指针指向一个虚函数表(简称虚表),虚函数表中存储了虚函数的入口地址。基类当中有虚函数时,会产生该虚函数表;创建基类对象,对象中的vPtr会指向该表;调用虚函数时,是通过vPtr在此表当中寻找函数入口地址的。
当派生类继承含有虚函数的子类时,会复制一份虚函数表,派生类如果有与基类中虚函数同名的虚函数,会在虚函数表中覆盖原来基类的虚函数;如果虚函数不重名,只会在虚函数表中增加一个函数入口。这种机制实现了类的多态。
如下面的例子:
#include <iostream> using namespace std; class A { public: A(int x=0) { cout<<"A"<<x<<endl; } void printA() { cout<<"Hello A"; } }; class B :public A{ public: B(int x=0) { cout<<"B"<<x<<endl; } virtual void printB() { cout<<"Hello B"; } }; class C : public B{ public: C() { cout<<"C"<<endl; } virtual void printC() { cout<<"Hello C"; } }; int main() { A a; B b; C c; cout<<"size of a:"<<sizeof(a)<<endl; cout<<"size of b:"<<sizeof(b)<<endl; cout<<"size of c:"<<sizeof(c)<<endl; return 0; }
VS类结构图:
运行结果为:
类A没有虚函数,因此大小仍然是1。类B因为有虚函数,其对象当中包含了一个vPtr指针,指针指向类B的虚函数表(假设为vTB),该表中存储了printB的入口地址,因此大小为4。类C因为继承了类B,也就复制了vTB(设为vTC),其对象中也就包含了指向vTC的虚表指针,该虚表中除了有printB的入口地址外,还包含了printC的入口地址,因此,类C对象大小为4。
考虑另一种情况,类C同时继承了类A、B,类A、B当中都有虚函数。如下面的例子:
#include <iostream> using namespace std; class A { public: A(int x=0) { cout<<"A"<<x<<endl; } virtual void printA() { cout<<"Hello A"; } }; class B { public: B(int x=0) { cout<<"B"<<x<<endl; } virtual void printB() { cout<<"Hello B"; } }; class C : public B, public A{ public: C() { cout<<"C"<<endl; } void printC() { cout<<"Hello C"; } }; int main() { A a; B b; C c; cout<<"size of a:"<<sizeof(a)<<endl; cout<<"size of b:"<<sizeof(b)<<endl; cout<<"size of c:"<<sizeof(c)<<endl; return 0; }
VS类结构图:
运行结果为:
类A、B对象的大小按照上面所说的内存很好理解。类C因为同时继承了类A、B,因此就复制了两个虚函数表,也就有了两个vPtr,所以大小为8。如果类C有虚函数,也会放在其中一张虚函数表当中,不会再增加对象大小。
含有成员变量时,按照《C++类对象大小的计算(一)常规类大小计算》所讲内容加上相应的大小即可。
下面的文章《C++类对象大小的计算(三)含有虚函数、虚继承类大小计算》会讨论增加虚继承时,类对象的大小。
相关文章推荐
- C++类对象大小的计算(三)含有虚函数、虚继承类大小计算
- C++ 类对象大小计算(二)含有虚函数类
- C++类对象大小的计算(一)常规类大小计算
- sizeof计算含有虚函数的类对象的大小
- char 类型的移植问题与C++类对象的sizeof()大小计算
- Java程序计算各种对象所占内存的大小的方法
- 关于类对象大小的 sizeof 计算问题
- 如何计算托管对象的大小
- C++类大小计算
- (转)C++类的实例化后占内存的大小计算
- 根据UIImage对象计算文件大小
- 关于类对象大小的 sizeof 计算问题
- C++类的大小的计算
- 关于空类 含有虚函数类 占有空间大小
- sizeof()计算一个类的对象大小和sizeof(string)的问题
- 精确计算一个Java对象占用的内存大小
- java对象占用内存大小计算方法
- 关于类对象大小的 sizeof 计算问题(续)
- 计算某个文件或文件夹的大小 文件夹内可能含有子文件夹
- C++类所占内存大小计算