C++之各种稀奇古怪的sizeof问题

248 阅读2分钟

1. 空class的size

class A{};

空class的size为1。每一个对象在内存空间里都有唯一的地址,如果size为0则没有办法分配地址。所以会给他1个byte的大小。如果都是0这个class有多个实例的时候并不能区别出多个实例。此外C++也规定了sizeof的值大于0

2. 只有函数(没有虚函数)的class

函数是不占用空间的所以大小取决于其他的因素。由于空的class为1,这种情况也是1。

class A{
    void func(){}
};

3. 含有虚函数的class

存在虚函数的时候需要额外的空间存储虚表指针。在64位的操作系统下虚表大小为8个byte。所以这种情况下是8个byte。

class A{
    virtual void func(){}
};

4. 多继承且存在虚函数

class A{
    virtual void funcA(){}
};

class B{
    virtual void funB(){}
};
class Cpublic A, B{
    virtual void funcC(){}
};

在继承的时候会针对不同的父类建立不同的虚表。C继承了2个所以有两个虚表。size为8 + 8 = 16

5. 存在static变量

static变量是类共享的因此并不占用空间。所以这个例子里还是1。

class A{
    static int num;
};

6. 存在普通成员变量。没有内存对齐情况。

这种情况很简单,就是简单的计算叠加。一个int 4个byte,所以就是4 + 4 = 8。顺便粘一下常见的变量大小。

![](https://upload-images.jianshu.io/upload_images/23475747-39796f96f951e9f1.png?imageMogr2/auto-orient/strip|imageView2/2/w/832/format/webp)
不同种类变量大小
class A{
    int num1;
    int num2;
};

7.普通变量,存在内存对齐。

C++为了使得访问更快会默认字节对齐,所谓字节对齐就是使用最大的粒度作为这个类的基本单位。比如有4byte和8byte的统一使用8byte

class A{
    int int_num;
    long long_num;
};

在64位的操作系统上就是8 + 8 = 16。虽然int是4个但是发生了字节对齐就变成了8。

8. 存在虚继承情况。

虚继承是为了解决多继承的菱形问题。但是多继承实在是太屑了我就没有研究。

9. 存在引用变量

class A{
public:    
    A(int& a) : v(a){    };
    int& v;
};

引用本质是使用指针实现的所以这里也是一个指针的大小为8。值得注意是对引用对象sizeof的话 比如sizeof(a.v),返回的大小则是引用指向的内容的大小,即是4。