C++ 字节对齐和sizeof()

1、结构体/类大小 字节对齐问题(使用 sizeof 验证)

1)简单数据类型:无需对齐

有sizeof(int)=4,sizeof(double)=8。对于数组而言有:

#include<iostream>
using namespace std;

int main()
{
    int a[3];
    cout<<sizeof(a);
    return 0;
}

输出结果为12。所以数组的大小即为数组数×sizeof(datatype)

2)结构体/类中:编译器需要字节对齐

1、成员的偏移量必须是成员长度的整数倍(对于第一个成员,0算任何数的整数倍)
2、结构体的大小是所有成员大小的整数倍(即,是所有成员的公倍数)

class A
{
public:
};

int main()
{
    /**
     * @brief 16  字节对齐、静态变量不影响类的大小、vptr指针=8
     */
    cout << sizeof(A) << endl;
    return 0;

对应例1:sizeof长度对应

class A //1
{
public:
   char b;
};

class A //4
{
public:
   int k;
};

class A//8
{
public:
   char b;
   int k;
};

class A //16,其中cp1-cp4填充1四字节,cp5填充1四字节
{
public:
   char b;
   int k;
   char cp1;
   char cp2;
   char cp3;
   char cp4;
   char cp5;
};

class A//20 ,b、cp2分别占四字节
{
public:
   char b;
   int k;
   char cp2;
   int p;
   char cp;
   char cp3;
   char cp4;
};

对应例2:必须是所有成员变量的公倍数

大小:32 ,以148为单位向前填充

class A//32
{
public:
   char b;//8
   double k;//16
   char cp2;//20
   int p;//24
   char cp;//25
   char cp3;//26
   char cp4;//27,填充至32
};

2、结构体/类的大小计算:含空,虚函数,静态变量等问题

1)空类大小:1
class A{};
int main()
{
    cout<<sizeof(A)<<endl;
    return 0;
}

sizeof输出:1
2)静态变量、成员函数(静态、非静态、虚函数本身)都不占长度
class A {
    static int a;
    int add(static int a) {
        return a + a;
    };
};

sizeof输出:1
3)含虚函数时,无论包含多少个,只占一个虚函数指针vcptr的长度(8)
无实际占用量、单虚函数:(1class A {
    int add() {};
    virtual void fun() {};
};

sizeof输出:8

有占用量、单虚函数:
class A {
    int b;
    int add(static int a) {
        return a + a;
    };
    virtual void fun() {};
};

sizeof输出:16

多个虚函数时:
class A {
    int b;
    int add(static int a) {
        return a + a;
    };
    virtual void fun() {};
    virtual void fun2() {};
};

sizeof输出:16
4)普通继承,派生类继承父类所有成员,要同时依照本类和父类进行对齐;类内使用其他类,也要相应按照成员对齐。
#include<iostream>
using namespace std;
class A
{public:
        char a;
        int b;
};

class B :public A {
};

class C :A {
public:
    short a;
    long b;
};

class D {
    A a;
    char c;
};


int main()
{
    cout << sizeof(A) << endl;//8
    cout << sizeof(B) << endl;//8
    cout << sizeof(C) << endl;//16
    cout << sizeof(D) << endl;//12

    return 0;
}

sizeof输出:881612
5)虚继承、虚函数继承,存疑

#include<iostream>
using namespace std;
class A
{
    virtual void fun() {}
};
class B
{
    virtual void fun2() {}
};
class C : virtual public  A
{
public:
    virtual void fun3() {}
};

class C1 : virtual public  A
{
};

class D : virtual public  A, virtual public B
{
public:
    virtual void fun4() {}
};

int main()
{
    /**
     * @brief 8 8 21 16 32 派生类虚继承多个虚函数,会继承所有虚函数的vptr?
     */
    cout << sizeof(A) << " " << sizeof(B) << " " << sizeof(C) << " " << sizeof(C1) << " " << sizeof(D) << endl;

    return 0;
}
6)可能存在编译器优化
 * @brief 此时B按照顺序:
 * char a
 * int b
 * short a
 * long b
 * 根据字节对齐4+4+8+8=24
 * 
 * 或编译器优化
 * char a
 * short a
 * int b
 * long b
 * 根据字节对齐2+2+4+8=16

参考添加链接描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值