C++中,类的sizeof运算结果

考虑一个类(或对象)的sizeof运算结果时,有一些细节需要注意。比如空类,是否sizeof结果就为0;成员函数(虚/实)会占多大空间等。

1. 空类的大小

像如下,定义一个空类:

class VoidClass
{
};

用sizeof(VoidClass)计算VoidClass的大小,结果会是:1

虽然空类本身没有任何空间需求,但是为了实例化,必须要让其对象占用一定的空间(这里分配了1个字节),否则会有两个对象地址相同的情况出现,如:

VoidClass a, b;

显然 &a != &b; 但如果编译器只分配了0个字节给其对象,会造成其对象和邻近定义的其它变量无法区分。

对于只有成员函数,没有成员变量的类:

class Other
{
public:
    void SayBye() {cout << "bye" << endl;}
};

sizeof(Other)的结果为 1

sizeof的参数是类型时,计算的是该类型的变量所占的空间。成员函数存放在代码段中,sizeof不统计这部分大小。


2. 包含虚函数的类

下面定义了一个只包含虚析构函数的类:

class VirtualBase
{
public:
    virtual ~VirtualBase() {}
};

在64位机器,sizeof(VirtualBase)的结果是: 8

如果类中有虚函数,编译器会在数据段中存放一个虚表,在类中会生成一个成员变量----虚指针(占用1个字空间,64位环境是8字节)。


继承类 VirtualBase,派生子类DerivedA,DerivedB,DerivedC:

class DerivedA : public VirtualBase
{
public:
    virtual ~DerivedA() {}
    virtual void SayHi() {cout << "hi" << endl;}
};


class DerivedB : public VirtualBase
{
public:
    virtual ~DerivedB() {}
    virtual void SayHi() {cout << "hi" << endl;}
private:
    int b;  
};


class DerivedC : public VirtualBase
{
public:
    virtual ~DerivedC() {}
    void SayBye() {cout << "bye" << endl;}
private:
    int b;  
};


class DerivedD : public VirtualBase
{
public:
    virtual ~DerivedD() {}
    virtual void SayHi() {cout << "hi" << endl;}
    void SayBye() {cout << "bye" << endl;}
private:
    int b;  
    int c;  
};
其中,A只有一个虚析构函数和一个虚函数,B在A基础上增加了一个int成员变量,C把B的虚函数变成了实函数,D在C基础上又增加了一个int成员变量。

A的大小是8,占空间的是虚指针; 

B的大小是16,虚指针8字节,int4字节,另外补充了4个填充字节,用于对齐。这里的填充说明一件事,我们这里使用的编译器,把虚指针放到了对象的其它成员变量的后面

C和B一样大。

D的大小仍然是16,这里不需要填充空白字节对齐了。


3. 完整代码

class VoidClass
{
};

class VirtualBase
{
public:
    virtual ~VirtualBase() {}
};

class DerivedA : public VirtualBase
{
public:
    virtual ~DerivedA() {}
    virtual void SayHi() {cout << "hi" << endl;}
};

class DerivedE : public VirtualBase
{
public:
    void SayHi() {cout << "hi" << endl;}
};

class DerivedB : public VirtualBase
{
public:
    virtual ~DerivedB() {}
    virtual void SayHi() {cout << "hi" << endl;}
private:
    int b;  
};

class DerivedC : public VirtualBase
{
public:
    virtual ~DerivedC() {}
    void SayBye() {cout << "bye" << endl;}
private:
    int b;  
};


class DerivedD : public VirtualBase
{
public:
    virtual ~DerivedD() {}
    virtual void SayHi() {cout << "hi" << endl;}
    void SayBye() {cout << "bye" << endl;}
private:
    int b;  
    int c;  
};

class Other
{
public:
    void SayBye() {cout << "bye" << endl;}
};

为了方便观察sizeof结果,定义了如下的宏:

#define SHOW_SIZE(t) cout << #t << " size: " << sizeof(t) << endl;

执行下面的main函数:

int main()
{
    SHOW_SIZE(VoidClass);
    SHOW_SIZE(VirtualBase);
    SHOW_SIZE(DerivedA);
    SHOW_SIZE(DerivedB);
    SHOW_SIZE(DerivedC);
    SHOW_SIZE(DerivedD);
}

得到的结果为:

VoidClass size: 1
VirtualBase size: 8
DerivedA size: 8
DerivedB size: 16
DerivedC size: 16
DerivedD size: 16


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值