从C语言到C++:结构体/类的大小

本文尽量全面覆盖计算结构体/类的大小计算的所以知识点,故每一部分不会写的很详细,若有不准确的地方可以在评论去讨论。

计算结构体大小时比较难且失误率比较高的面试题,实际变成中,个人感觉用处不大。

字节对齐的好处是提供CPU读效率,防止一次读对应多次汇编指令。在编写有关数据帧时,可使用“#pragma pack(1)”来取消字节对齐。数据帧要提供读效率的话,应从数据帧协议出直接考虑,而不是让结构体自动帮我们添加,这样容易出错。

目录

1 C语言中结构体大小(字节对其原则)

2 测试程序1

2.1 平台测试程序:

2.2 结构体大小理解测试程序:[3]

2.3 结构体套结构体测试:[4]

3 C++类对象的大小

4 测试程序2

4.1 继承顺序问题

4.2 虚函数表的位置

5 参考资料


1 C语言中结构体大小(字节对其原则)

前提:熟悉在不同系统下基本类型的大小。[1][2]

第一步:default setting : platform_alignment_size == (systemBits / 8) or "#pragma pack(x)" setting

第二步:max_elemVar_size = min(max_elemVar_size, platform_alignment_size )

1、class_pos_begin % Xmax_elemVar_size == 0

2、 class_size %  Xmax_elemVar_size == 0

3、 if elemVar is nested class, then ,elem_size = max_elemVar_size in nested class.

    Xelem_size = min(elem_size, platform_alignment_size)    ,    pos_elem % Xelem_size == 0

:elemVar为成员变量,X前缀表示修正量,pos表示位置,

确定平台的简单方法:平台简单说是由CPU、OS 和Compiler组成的,要使用64位的平台,那么CPU应该是支持64位的,OS应选择64位的,Compiler也应选择64位的,缺一不可。

4、特例:空结构体的大小为1字节。

2 测试程序1

2.1 平台测试程序:

#include <iostream>
#pragma pack()
int main()
{
        cout << "sizeof(void*):" << sizeof(void*) << endl;
        cout << "sizeof(char):" << sizeof(char) << endl;
        cout << "sizeof(short):" << sizeof(short) << endl;
        cout << "sizeof(int):" << sizeof(int) << endl;
        cout << "sizeof(long):" << sizeof(long) << endl;
        cout << "sizeof(long long):" << sizeof(long long) << endl;
        return 0;
}

2.2 结构体大小理解测试程序:[3]

#include <iostream>
// 字节对齐长度->程序输出结果:1->13 2->14 4->16 8->24
#pragma pack(4)
using namespace std;
struct S2_t
{
    int a ;
    double c ;
    char b ;
};
#pragma pack()
int main()
{
    cout<<sizeof(S2_t)<<endl;
    return 0;
}

//attention: struct S3_t{cha a,b,c};, sizeof(S3_t) always 3

2.3 结构体套结构体测试:[4]

#pragma pack(8):
struct TestStruct4
{
        char a;
        long b;//假设是4字节的long
};
struct TestStruct5
{
        char c;
        struct TestStruct4 d;
        long long e;
};

siseof(struct TestStruct5)==24

所在字节位置为:1xxx 1xxx 1111 xxxx 11111111

3 C++类对象的大小

在C语言结构体大小理解的基础上,还需要考虑:[6]

  • 类的大小与普通数据成员有关,与成员函数和静态成员无关。即普通成员函数,静态成员函数,静态数据成员,静态常量数据成员均对类的大小无影响。[5]
  • 虚函数对类的大小有影响,是因为虚函数表指针带来的影响。
  • 虚继承对类的大小有影响,是因为虚基表指针带来的影响。
  • 空类的大小是一个特殊情况,空类的大小为1。

1、继承时:当派生类继承空类后,派生类如果有自己的数据成员,而空基类的一个字节并不会加到派生类中去;

2、作为嵌套的成员变量:看做1个字节的成员函数;

3、各嵌套的类都为空:总大小为1个字节。

计算C++对象的大小过程中,最重要的就是需要知道哪些成员变量在前,哪些成员变量在后。这个问题再存在继承和虚函数是将变得比较复杂。

4 测试程序2

注:以下测试实在vs32下进行的,

4.1 继承顺序问题

#include<iostream>
using namespace std;
#pragma pack(8)
class A
{
    char a=1;
};

class B
{
    double b=2;
};

class C :public A, public B
{
    int c=3;
};


int main(void)
{
    C cc;
    cout << sizeof(void*) << endl;
    cout << sizeof(cc)<<endl;
    return 0;
}

故占用大小为24个字节。

4.2 虚函数表的位置

5 参考资料

注:参考资料的准确性请自行判断,笔者不做评价。

[1]64位机器中int占几个字节 

[2]windows和linux下各类型字节长度  

[3]C语言中结构体对齐问题  

[4]关于内存对齐

[5]C结构体中不允许有静态变量

[6]c++类的大小计算

[7]C++面试题之虚函数(表)实现机制

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值