一、类的大小与对象的大小
类只是一种类型,没有大小可言。使用sizeof得到的大小,只是它的实例化对象的大小。所以类的大小与对象的大小是一样的。
class Base
{
private:
int a;
int b;
};
void main()
{
Base base;
int objSize = sizeof(base);
int classSize = sizeof(Base);
cout << objSize << endl; // 8
cout << classSize<< endl; // 8
}
二、空类的大小
一个类什么都没有定义,它的大小不是0,而是1。
类的实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。第一点说到类的大小跟对象大小一样,所以空类的大小是1.
class Base
{
};
int size = sizeof(Base); // size == 1
三、类成员变量
如果一个类有类成员变量(static修饰的成员变量),那么类的大小又应该怎么算呢?类的大小其实就是对象的大小,类成员不属于对象,所以类的大小也不包括类成员变量。
class Base
{
public:
Base(){};
void f();
private:
int a;
int b;
static int sc;
};
int size = sizeof(Base); // size == 8
四、子类的大小
子类继承父类,所以子类的大小等于父类的大小加上自己定义的成员变量的大小。
class Base
{
public:
Base(){};
void f();
private:
int a;
int b;
static int sc;
};
class Derived : public Base
{
int d;
};
int derivedSize = sizeof(Derived); // derivedSize == 12
四、带有虚函数的类的大小
类的普通函数不算类的大小,虚函数稍微复杂些。虚函数本身也不计算大小,但是虚函数表计算大小。类只要有虚函数就有虚函数表,在类里面有一个指针指向虚函数表。这个指针大小是4,所以具有虚函数的类它的大小要在原来基础上加4。但是不管有多少个虚函数,都只加4。(多重继承例外)
class Base
{
public:
Base(){};
virtual void f(); // 三个虚函数,类的大小只增加4
virtual void g();
virtual void h();
private:
int a;
int b;
};
int size = sizeof(Base); // size == 12
五、具有虚函数的子类的大小
具有虚函数的子类的大小,其虚函数指针也是4,所以大小在原基础上加4。以下例子,虽然Child和GrandChild都定义了自己的虚函数,但是类的大小跟父类一样只增加4。
class Base
{
public:
Base(){};
virtual void f();
virtual void g();
virtual void h();
private:
int a;
int b;
static int sc;
};
class Child : public Base
{
public:
virtual void f();
virtual void m(); //Child 的虚函数
};
class GrandChild : public Child
{
public:
virtual void f();
virtual void n(); // GrandChild 的虚函数
};
int base= sizeof(Base); // 12
int child = sizeof(Child); // 12
int grandchild = sizeof(GrandChild); // 12
六、注意补齐
为了便于访问数据,编译器会对数据进行补齐。不举例子了。