一、空类的大小
#include <iostream>
class A{};
int main()
{
A obja;
std::cout << "obja 的地址:" << &obja << std::endl;
std::cout << "obja 的大小:" << sizeof(obja) <<" B "<< std::endl;
return 0;
}
结果:
obja 的地址:0x7fff69557457
obja 的大小:1 B
解释:
因为对象 obja 在内存中是存在的,尽管 A 没有任何成员函数以及成员变量。为了表征该 obja 的存在,所以编译器选择了一个最节省空间的方法,就是用 1B 来表示该对象。
二、含有普通成员变量的类对象的大小
#include <iostream>
class A
{
char c;
int k;
};
int main()
{
A obja;
std::cout << "obja 的大小:" << sizeof(obja) <<" B "<< std::endl;
return 0;
}
结果:
obja 的大小:8 B
解释:
这里面有个内存对齐的原因,所以 obja 对象的大小是 8B 。
三、含有静态成员变量的类对象的大小
#include <iostream>
class A
{
public:
char c;
int k;
public:
static int count;
};
int A::count = 10;
int main()
{
A obja;
std::cout << "obja 的大小:" << sizeof(obja) <<" B "<< std::endl;
return 0;
}
结果:
obja 的大小:8 B
解释:
静态成员变量不占用对象空间,该变量保存在全局变量区。
四、含有成员函数的类对象的大小
#include <iostream>
class A
{
public:
char c;
int k;
public:
void func1(){}
static void func2(){}
};
int main()
{
A obja;
std::cout << "obja 的大小:" << sizeof(obja) <<" B "<< std::endl;
return 0;
}
结果:
obja 的大小:8 B
解释:
上述测试结果是成员函数(静态和非静态)并不占用对象的空间,因为所有的对象公用一套成员函数的代码,所以若每个对象都存储一套函数代码就太浪费了,所以C++编译器将成员函数的代码放在了内存中的代码区。
五、综述
拓展:
C++程序内存布局分为 全局数据区(data area)、代码区(code area)、栈区(stack area)、堆区(heap area)。
类别 | 存储位置 |
类对象 | 栈区 / 堆区 |
普通成员变量 | 类对象 |
静态成员变量 | 全局数据区(属于类) |
普通成员函数 | 代码区(属于类) |
静态成员函数 | 代码区(属于类) |
(SAW:Game Over!)