一、结构体在内存中占用的字节数示意图
字节对齐问题:字节对齐是为了提高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
小白第二次写博客,如有不及之处,大家多多理解,有啥问题可以都提出来,谢谢,嘻嘻。