类或者对象的大小可以用sizeof运算符算出,即sizeof(object_name)。可是sizeof(object_name)的值与其成员的大小是什么关系呢,答案是:一个对象的大小>=所有非静态成员大小的总和。
为什么是大于等于而不是正好相等呢?超出的部分主要有以下两方面:
1) C++对象模型本身
对有虚函数的类来说,必须为它的对象提供运行时类型信息(RTTI,Run-Time Type Information)和关于虚函数表的信息,常见的做法是在对象中放置一个指向虚函数表的指针,此外,为了支持RTTI,许多编译器都把该类型信息放在虚函数表中。但是,是否必须采用这种实现方法,C++标准没有规定,主流编译器均采用的一种方案。
2) 字节对齐
因为对于大多数CPU来说,CPU字长的整数倍操作起来更快,因此对于这些成员加起来如果不够这个整数倍,有可能编译器会插入多余的内容凑足这个整数倍,此外,有时候相邻的成员之间也有可能因为这个目的被插入空白,这个叫做“补齐”(padding)。所以,C++标准紧紧规定成员的排列按照类定义的顺序,但是不要求在存储器中是紧密排列的。
基于上述两点,可以说用sizeof对类名操作,得到的结果是该类的对象在存储器中所占据的字节大小,由于静态成员变量不在对象中存储,因此这个结果等于各非静态数据成员(不包括成员函数)的总和加上编译器额外增加的字节。后者依赖于不同的编译器实现,C++标准对此不做任何保证。
C++标准规定类的大小不为0,空类的大小为1,当类不包含虚函数和非静态数据成员时,其对象大小也为1。
如果在类中声明了虚函数(不管是1个还是多个),那么实例化对象时,编译器会自动在对象里放置一个指针指向虚函数表VTable,它是实现多态的关键点。但虚函数本身和其他成员函数一样,是不占用对象的空间的。
我们来看下面一个例子:
#include <iostream> using namespace std; class A { }; class B { char ch; void func(){ } }; class C { char ch1; //占用1字节 char ch2; //占用1字节 virtual void func(){ } }; class D { int in; virtual void func(){} }; int main() { A a; B b; C c; D d; cout<<sizeof(a)<<endl;//result=1 cout<<sizeof(b)<<endl;//result=1 cout<<sizeof(c)<<endl;//result=8 cout<<sizeof(d)<<endl;//result=8 }
综上所述:
虚函数、成员函数[包括静态与非静态]、和静态数据成员都是不占用对象的存储空间的
对象大小 = vptr(可能不止一个) + 所有非静态数据成员大小 + 因对齐而多占的字节
原文:http://blog.csdn.net/liukang325/article/details/43675641