对象在内存中的长度不一定等于sizeof(Member_1) + sizeof(Member_2) +...+ sizeof(Member_n),因为有三种情况需要考虑:
1.空类:空类中没有任何数据成员,按理说此类的对象长度为0,则不占任何空间.但实际情况是,空类的长度为1 byte.如果对象完全不占用任何空间,那么空类就无法取得实例对象的地址, 则this指针失效,同时也无法实例化.而类的定义是由成员函数和成员数据组成的,在没有成员数据的情况下还可以有成员函数,因此任然需要实例化,所以空类也分配了一个字节用于类的实例化,但这1个字节数据并没有被使用.
01
#include <iostream>
02
03 using namespace std;
04
05 class CTest
06 {
07 public:
08 void PrintHello() { cout << "hello" << endl; }
09 };
10
11 int _tmain( int argc, _TCHAR* argv[])
12 {
13 CTest test;
14 int nSize = sizeof(test);
15 return 0;
16 }
02
03 using namespace std;
04
05 class CTest
06 {
07 public:
08 void PrintHello() { cout << "hello" << endl; }
09 };
10
11 int _tmain( int argc, _TCHAR* argv[])
12 {
13 CTest test;
14 int nSize = sizeof(test);
15 return 0;
16 }
2.有静态数据成员的类:静态数据成员和静态变量原理相同,都是一个含有作用域的特殊全局变量,因此静态数据成员的初值会被写入编译链接后的执行文件中.当程序被加载时,OS将执行文件中的静态成员数据读到对应的内存单元里,此时静态数据成员已经存在,但类还没有实例化对象.所以静态数据成员不属于某一对象,它仅仅是与类相关.即,静态数据成员也不参与对象长度的计算.
01
#include <iostream>
02
03 using namespace std;
04
05 class CStatic
06 {
07 public:
08 int m_Int; //4bytes
09 int m_IntAnother; //4bytes
10 static int m_sInt;
11 };
12
13 int CStatic::m_sInt = 0x12345678;
14
15 int _tmain( int argc, _TCHAR* argv[])
16 {
17 CStatic test;
18 int nSize = sizeof(test);
19
20 return 0;
21 }
02
03 using namespace std;
04
05 class CStatic
06 {
07 public:
08 int m_Int; //4bytes
09 int m_IntAnother; //4bytes
10 static int m_sInt;
11 };
12
13 int CStatic::m_sInt = 0x12345678;
14
15 int _tmain( int argc, _TCHAR* argv[])
16 {
17 CStatic test;
18 int nSize = sizeof(test);
19
20 return 0;
21 }
如下可发现,静态数据成员并没有参与对象长度的计算
3.内存对齐:类和结构体中的数据成员是根据它们在类或结构体出现的顺序依次申请内存空间的.由于内存对齐的原因,它们排列在内存中需要遵守一定的规则.