使用sizeof()计算类的大小

      《剑指offer》这本书里第22页有讲到sizeof()计算类大小的问题,在网上查阅了一些资料,进行了一些总结。欢迎补充指正!

1、类的大小

      类的sizeof()大小一般是类中的所有成员的sizeof()大小之和,这个就不用多说。确切的说,用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小。注意:类只是一个类型定义,它本身是没有大小可言的。

        对象大小=   vptr(可能不止一个,这个很难确定,类中定义了一个virtual函数,仍然为占用4个字节)   +   所有非静态数据成员大小   +   Aligin字节大小(依赖于不同的编译器)。

2、使用sizeof()计算类大小的一些基本原则

       (1)类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑;

       (2)类的总大小也遵守类似class字节对齐的,调整规则;(参考5分钟搞定内存字节对齐)

       (3)成员函数都是不会被计算的;

       (4)如果是子类,那么父类中的成员也会被计算;

       (5)虚函数由于要维护虚函数表,所以要占据一个指针大小,也就是4字节。

总结即:一个类中,虚函数、成员函数(包括静态与非静态)和静态数据成员都不占用类对象的存储空间。

3、空类的大小

     《剑指offer》里的分析:空类型的实例中不包含任何信息,本来求sizeof的结果应该是0,但是当我们声明该类型的实例时,必须在内存中占有一定得空间,否则无法使用这些实例。至于占多少内存,由编译器决定。在Visual Studio中,每个空类型的实例占用1字节的空间。

       因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof()为1。

4、编程举例

#include<iostream>

using namespace std;

//1、空类
class empty_class
{
	
};

class empty_class1
{
public:
	empty_class1();
	~empty_class1();
};

//2、虚函数
class virtual_class
{
public:
	virtual_class();
	virtual ~virtual_class();
};

class example1_class
{
private:
	int a;	
};

class example2_class
{
public:
	example2_class();
	virtual ~example2_class();   //若去掉virtual关键字,则sizeof(example2_class)结果为4
	int count(int num){a = num;} //普通成员函数,为各实例公有,不归入sizeof统计
private:
	int a;	
};

class example3_class
{
public:
	example3_class();
	virtual ~example3_class();   //若去掉virtual关键字,则sizeof(example2_class)结果为4
	virtual int count(int num){a = num;}  //虚函数不记入sizeof统计
private:
	int a;	
};

class example4_class
{
public:
	virtual int count(int num){}  <span style="font-family: Arial;">//虚函数记入sizeof统计
</span>private:
	int a;	
};

class example5_class
{
private:
	float a;
	//double b;
	//int c;
public:
	void fun(void);//不记入sizeof统计
};

class example6_class    //该类里面包含一个函数和一个虚函数,取最大的占用4个字节
{
    void func_1() {}
    void func_2() {}
    virtual void func_3() {}
    virtual void func_4() {}
};

//3、继承
class inherit_class:public example2_class
{
public:
	inherit_class();
	~inherit_class();
private:
	char ch;
	char *pch;
	const float f;
	static double d; //不计入sizeof计算
};

int main()
{
	cout<<"sizeof(empty_class) = "<<sizeof(empty_class)<<endl;
	cout<<"sizeof(empty_class) = "<<sizeof(empty_class1)<<" with constructer and deconstructer"<<endl;
	cout<<"sizeof(virtual_class) = "<<sizeof(virtual_class)<<" with virtual"<<endl;
	cout<<"sizeof(example1_class) = "<<sizeof(example1_class)<<endl;
	cout<<"sizeof(example2_class) = "<<sizeof(example2_class)<<endl;
	cout<<"sizeof(example3_class) = "<<sizeof(example3_class)<<endl;
	cout<<"sizeof(example4_class) = "<<sizeof(example4_class)<<endl;
	cout<<"sizeof(example5_class) = "<<sizeof(example5_class)<<endl;
	cout<<"sizeof(example6_class) = "<<sizeof(example6_class)<<endl;
	cout<<"sizeof(inherit_class) = "<<sizeof(inherit_class)<<" with inherit"<<endl;

	system("pause");
	return 0;
}

再举一个“阿里巴巴2017实习生笔试题”:

#pragma pack(2)
class BU
{
    int number;
    union UBffer
    {
        char buffer[13];
        int number;
    }ubuf;
    void foo(){}
    typedef char*(*f)(void*);
    enum{hdd,ssd,blueray}disk;
}bu;

那么 sizeof(bu)的值是多少?

分析:一个Class对象占用内存空间为非静态成员变量总和+ 数据对齐处理+虚函数。int=4union=13+1=14enum=4(内存中当成int来存储)4+14+4=22,f只是一个定义,不是实际上的指针,没有占字节。另外 union的大小取决于它所有的成员中,占用空间最大的一个成员的大小,并且需要内存对齐,这里因为#pragma pack(2),所以union的大小为14,如果不写#pragma pack(2),那么union大小为16【因为与sizeof(int)=4对齐】。但是如果我加入一个int*。即:

class BU
{
int number;
union UBffer
{
char buffer[13];
int number;
}ubuf;
void foo(){}
typedef char*(*f)(void*);
enum{hdd,ssd,blueray}disk;
int *a;
}bu;
那么得到sizoef(bu)=30,int型指针占8个字节。


参考资料:

sizeof() 类大小,空类大小

使用sizeof计算类的大小

sizeof浅析(三)——求类的大小

类的大小——sizeof 的研究(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值