一个class对象需要占用的内存空间大小,最权威的结论是:
- 非静态成员变量总合
- 加上编译器为了CPU计算,作出的数据对齐处理
- 加上为了支持虚函数,产生的额外负担
可以分为基类和派生类两种情况来查看一个类占用的内存空间大小。
基类
(一)
class CBase
{
};
sizeof(CBase)=1;
c++要求每个实例在内存中都有独一无二的地址,空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。
(二)
class CBase
{
private:
int a;
char p;
};
sizeof(CBase)=8;
记得对齐的问题。int 占4字节,char占一字节,补齐3字节。
(三)
class CBase
{
private:
int a;
char p;
static int b;
}
sizeof(CBase)=8;
静态成员变量属于整个类,不单独属于某个对象。
(四)
class CBase
{
public:
void func();
private:
int a;
char p;
};
sizeof(CBase)=8;
成员函数只是在名义上是类里的。其实成员函数的大小不在类的对象里面,同一个类的多个对象共享函数代码。而我们访问类的成员函数是通过类里面的一个指针实现,而这个指针指向的是一个table,table里面记录的各个成员函数的地址.
(五)
class CBase
{
public:
CBase(void);
virtual ~CBase(void);
private:
int a;
char *p;
};
sizeof(CBase)=12
C++类中有虚函数的时候有一个指向虚函数表的指针(vptr),在32位系统分配指针大小为4字节。一个基类对象无论有多少个虚函数,只有这一个指针,4字节。在内存布局中,C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。
派生类
派生类的大小是本身成员变量的大小加上基类的大小。如果派生类继承了多个基类的虚函数,那个这个派生类的所有虚函数所占用的内存空间等于4*(基类个数),即为每个拥有虚函数的基类维护一张虚函数表。
class B1
{
public:
int x;
virtual void v1(){ cout << "B1::v1" << endl; }
void f1(){cout << "B1::f1" << endl; }
};
class B2
{
public:
int y;
virtual void v2(){ cout << "B2::v2" << endl; }
void f2(){ cout << "B2::f2" << endl; }
};
class B3
{
public:
int z;
virtual void v3(){ cout << "B3::v3" << endl; }
void f3(){ cout << "B3::f3" << endl; }
};
class D : public B1, public B2, public B3
{
public:
int a;
void v3(){ cout << "D::v3" << endl; }
virtual void vD(){ cout << "D::vD" << endl; }
};
内存布局为:
与单继承相同的是所有的虚函数都包含在虚函数表中,所不同的是多重继承有多个虚函数表,当子类对父类的虚函数有重写时,子类的函数覆盖父类的函数在对应的虚函数位置,当子类有新的虚函数时,这些虚函数被加在第一个虚函数表的后面。
原文地址:
http://blog.sina.com.cn/s/blog_69c189bf0100mkeu.html
http://www.cnblogs.com/itech/archive/2009/02/28/1399995.html