C++ 类的sizeof大小

1空类

class A {};

大小为1。
类的实例化就是给每一个实例在内存中分配一块地址。空类被实例化时,会由编译器隐含的添加一个字节。所以空类的size为1。
2 虚函数

class A
{
public:
virtual void fun() {};
virtual void fun2() {};
};

大小为4。
当C++类中有虚函数的时候,会有一个指向虚函数表(V-table)的指针,所有的虚函数都在这个表中。指针大小为4,所以size为4。

在来看如下代码:

class A
{
public:
    char b;
    short c;
    int a;
};
class B
{
public:
    char a;
    int c;
    short b;
};

考虑数据对齐,大小分别为 8 和 12。如果我们将int 换成虚函数,回事什么结果呢?

class A
{
public:
    char b;
    short c;
    virtual void fun() {}
};
class B
{
public:
    char a;
    virtual void fun() {}
    short b;
};

大小分别为 8 8。 都是占4个字节,结果不一样。 这是因为,为了效率问题,编译器(gcc 和 微软)一般会把虚指针放在类的内存空间的最前面的位置,不管虚函数声明的位置。考虑对齐,大小都是 4 +1+1+2 = 8.

3 静态数据成员

class A
{
public:
    char b;
    virtual void fun() {};
    static int c;
};

大小为8。
静态数据成员被编译器放在程序的一个global data members中,它是类的一个数据成员,但不影响类的大小。不管这个类产生了多少个实例,还是派生了多少新的类,静态数据成员只有一个实例。静态数据成员,一旦被声明,就已经存在。 考虑到数据对齐, 最终是8字节。

4 普通成员函数

class A
{
public:
    void fun() {};
};

大小为1。
类的大小与构造函数,析构函数,普通成员函数无关。

5 普通单继承

class A 
{
    int c;
};
class B : public A
{
    int a;
};

大小分别为4 和 8。 可以看到普通的继承就是基类的大小+派生类自身的大小。注意数据对齐。
注意:类的数据成员按其声明顺序加入内存,无访问权限无关,只看声明顺序。

class A
{
    int a;
    char b;
};
class C : public A
{
public:
    char c;
};

上面这段代码,不同的编译器结果不同,VS的结果是 8 和 12, GCC是8 和 8。VS中 相当于

class C
{
    A a;
    char c;
};

A的大小为8,对齐值为4, 则考虑总体对齐 8 + 1 + 3(padding) = 12。
GCC 则是

class C
{
    int a;
    char b;
    char c;
};

结果为 4 + 1 + 1 + 2 = 8。

6 含虚函数的单继承

class A
{
    virtual void fun () {}
};
class C : public A
{
public:
    virtual void fun2() {}
};

大小分别为4 和 4。派生类继承了基类的虚指针,所以大小为4。

7 虚单继承

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

class C : virtual public  A
{
public:
    virtual void fun2() {}
};

这段代码,VS和gcc结果不一样。VS为 4 和 12。 gcc为4 和4。

8 普通多继承

class A
{
    int a;
    char b;
};

class B
{
    char b;
};
class C : public  A, public B
{
public:
    char c;
};

VS:8 1 12
GCC:8 1 8
VS中相当于把A B当做整体看待, GCC则拆分整合。

9 虚函数多继承

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

class B
{
    virtual void fun2() {}
};
class C : public  A, public B
{
public:
    virtual void fun3() {}
};

结果为 4 4 8。分析:类A一个虚函数表,类B一个虚函数表,类C继承了两个虚函数表,并把自己的虚函数写在了继承顺序中第一个虚函数表中。

10 虚继承

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

class B
{
    virtual void fun2() {}
};
class C : virtual public  A, virtual public B
{
public:
    virtual void fun3() {}
};

GCC: 4 4 8
VS:4 4 16

  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhengjihao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值