C++进阶之类大小、字节对齐问题、虚函数在类中所占内存问题

 一、结构体在内存中占用的字节数示意图

字节对齐问题:字节对齐是为了提高CPU效率,windows下默认追加4位,根据实际情况而定。

就比如结构体A的字节数,从图中可以看出,存放的最长字节数位double类型为8,字节对齐即将及将结构体中每个字节都与最长的字节进行统一对齐,也就是说,char和int,各占8位,所以A结构体占24位。注意:存储时是根据定义的顺序进行顺序存储,就会发现,D结构体的内存,则占16位,a变量和c变量共同占5位,字节对齐后中则占8位,共计16位。

二、类的内存问题 

1)空类默认为一个字节

注意:空类其实是0字节,只是系统为了方便,强制给其分配一个内存,当类中有数据成员时,则抛弃这一个字节,

就比如下面的类中含有一个数据成员 char a;则下面的这个类大小是一个字节。

#include<iostream>
using namespace std;
class A{};
int main()
{
    cout<<"该类的字节数为:"<<sizeof(A)<<endl;//输出:该类的字节数为:1
    return 0;
}

2)类中的数据成员与成员函数所占的内存

1、数据成员根据所在的编译器位数决定,int,char,long 之类的。

注意:静态数据成员在类中不占内存!

数据成员的字节对齐:

下述中,a对齐为4个字节,与b一起共八个字节。

#include<iostream>

using namespace std;

class A{

char a;

int b;

};

int main()

{

cout<<"该类的字节数为:"<<sizeof(A)<<endl;//输出:该类的字节数为:8

return 0;

}

2、成员函数在类中不占内存。

注意:虚函数的虚指针在类中占内存,32位编译器为4位,64位编译器为8位,虚函数从虚函数表中分配内存,与数据成员所占内存不是同一位置!同时,一个类中有多个虚函数,只计算一个虚指针的大小!

3)继承与虚继承内存继承问题 

注意:

1、普通单继承,继承就是基类+派生类自身的大小(注意字节对齐)
注意:类的数据成员按其声明顺序加入内存,无访问权限无关,只看声明顺序。

#include<iostream>

using namespace std;

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

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

int main()

{

cout<<sizeof(A)<<endl;//输出:8

cout<<sizeof(B)<<endl;//根据字节对齐4+4=8+8+8=24 (64位编译器下,long 字节数位8)

}

虚函数的继承:

#include<iostream>

using namespace std;

class A{

virtual void f(){}

};

class B: public A{

};

int main()

{

cout<<sizeof(B)<<endl;//输出:4

}

你会不会疑问字节数为什么不是5?

解析:介绍空类时说到,类中有数据成员时,忽略空类的一个字节,虽然B类没有数据成员,但是他是继承于A类的,所以,也是四个字节。

2、虚继承

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

int main()
{
    cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C);

    return 0;
}

以下俩种编译器的输出,原理本人也有点搞不懂,有懂得,大家可以评论下,谢谢了。

32位系统编译器:

输出:4 4 16

如果去掉类C中fun3()虚函数,则输出4 4 12 ,如果改为普通继承,则输出,4 4 8,如果去掉fun3()的虚函数也是4 4 8,普通继承只继承基类的虚指针,自身的虚函数可以忽略。

64位系统编辑器:

输出:8 8 16

如果掉类C中fun3()虚函数,输出不变,去掉俩个虚函数,输出也是8 8 16,就和普通继承一样了。

 

结构体存储示意图来自:https://blog.csdn.net/Bigcat_u/article/details/82821326

部分示例:https://github.com/Light-City/CPlusPlusThings/tree/master/basic_content/sizeof

小白第二次写博客,如有不及之处,大家多多理解,有啥问题可以都提出来,谢谢,嘻嘻。

 

 

 

 

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值