C++中各种类的大小

注:本文测试实例使用的编译器版本为clang-703.0.29,系统int长度为4字节,指针长度为8字节。

1. 空类

class A {};

空类sizeof的结果为1,为什么不是0呢?因为C++标准规定两个不同实例的内存地址必须不同(戳这里),所以用这一个字节来占用不同的内存地址,让空类的两个实例可以相互区分。而大多数编译器支持空基类优化(Empty Base Class Optimization, EBCO),即从空基类中派生出来的类并不会增加1字节,如:

class B : A {
  int a;
};

sizeof(B)的结果为4而不是5或8。

2. 带静态数据成员的类

class C {
  int a;
  static int b;
};

sizeof(C)结果为4,静态数据成员被存放在类对象之外。

3. 带非虚函数成员的类

class D {
  public:
    void func1() {}
    static void func2() {}
};

sizeof(D)结果为1,无论是普通成员函数还是静态成员函数都被存放在类对象之外。

4. 带虚函数成员的类

class E {
  public:
    virtual void func() {}
};

sizeof(E)结果为8,带虚函数成员的类对象会包含一个指向该类的virtual table的指针。

5. 对齐规则

class F {
  char a;
  int  b;
};

sizeof(F)的结果为8而不是5,由于F的最大对齐值为4(int),因此a和b之间被补齐3字节。

6. 普通派生类

class G : public C {
  int a;
};

sizeof(G)的结果为8,派生类会存放基类中非静态数据成员(C中的a)的副本。

7. 基类带虚函数的派生类

class H : public E {};

sizeof(H)结果为8,由于基类中带虚函数,派生类中也必须保存一个指向派生类的virtual table的指针。

8. 多重继承的派生类

class I : public B, public C {};

sizeof(I)结果为8,B和C中非静态数据成员长度以及是否需要指向virtual table的指针的情况加和。

9. 多重继承下的对齐规则

class J : public B, public F {
  char a;
};

sizeof(J)结果为16,B、F和J类中共有两个int两个char,对齐后4*4结果为16。

10. 虚继承的派生类

class K : virtual public A {};

class L : virtual public B {};

sizeof(K)的结果为8,派生类中会存放一个指向虚继承基类唯一实例的指针。sizeof(L)的结果为16,因为对齐规则int被补齐。注意虚继承和虚函数是两个完全不同的概念,它们之间没有直接联系。

class M : virtual public A {};

class N : public K, public M {};

sizeof(N)的结果为16,虽然K类和M类中的虚继承指针指向了同一个基类实例,但它们是不同的指针,N类中需要同时存放这两个指针。

原文地址:https://www.cnblogs.com/openxxs/p/5400754.html