类对象的大小
- 确切的说,类只是一个类型定义,它是没有大小可言的。 用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小。(注意不要说类的大小,是类的对象的大小.)
- C++标准规定类的大小不为0,空类的大小为1,当类不包含虚函数和非静态数据成员时,其对象大小也为1。 如果在类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针指向虚函数表VTable,在32位机器上,一个对象会增加4个字节来存储此指针,它是实现面向对象中多态的关键。而虚函数本身和其他成员函数一样,是不占用对象的空间的
空类
什么是空类
class Student
{
};
- 通过利用sizeof求解,可以知道上述Student类的大小为1,那么很多人就会疑惑了,明明这个类中什么都没有,那么它的大小为什么是1而不是0呢?
- 实际上,这是类结构体实例化的原因,空的类或结构体同样可以被实例化,如果定义对空的类或者结构体取sizeof()的值为0,那么该空的类或结构体实例化出很多实例时,在内存地址上就不能区分该类实例化出的实例,所以,为了实现每个实例在内存中都有一个独一无二的地址,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址,所以空类所占的内存大小是1个字节。
一般的类
class base1
{
private:
char a;
int b;
double c;
};
class base2
{
private:
char a;
double b;
int c;
};
- base 1类对象的大小为16字节,而base 2类对象的大小为24字节,因为不同的声明顺序,居然造成了8字节的空间差距,因此,我们将来在自己声明类时,一定要注意到内存对齐问题,优化类的对象空间分布。
class Base
{
private:
char a;
public:
virtual void f();
virtual void g();
};
class Derived:public Base
{
private:
int b;
public:
void f();
};
class Derived1:public Base
{
private:
double b;
public:
void g();
virtual void h();
};
类的大小与什么有关系
- 与类大小有关的因素:普通成员变量,虚函数,继承(单一继承,多重继承,重复继承,虚拟继承)
- 与类大小无关的因素:静态成员变量,静态成员函数及普通成员函数
总结
- 类的大小为类的非静态成员数据的类型大小之和.
- 由编译器额外加入的成员变量的大小,用来支持语言的某些特性(如:指向虚函数的指针).
- 为了优化存取效率,进行的边缘调整(类似于结构体的内存对齐)
- 与类中的构造函数,析构函数以及其他的成员函数无关.
- 一个类中,虚函数、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的。
- 对象大小= vptr+ 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器)