^ _ ^ 
查看占用内存大小的方式
基础类型在内存中的大小
| 类型 | 
所占大小(字节) | 
| int | 
4 | 
| long | 
4 | 
| short | 
2 | 
| char | 
1 | 
| 指针 | 
8 | 
| long long | 
8 | 
| float | 
4 | 
| double | 
8 | 
结构体中的内存对齐
就近原则
根据最近的下一个变量的大小进行对齐,最后一个变量则是根据它的上一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | 例1: char a[3]; int b; 因为a最邻近的b是int类型,因此a按照int类型的大小(4字节)进行对齐,a和它之前的所有成员变量所占内存之和应该为4的倍数
  例2: char a[3]; long long b; 因为a最邻近的b是int类型,因此a按照long long类型的大小(8字节)进行对齐,a和它之前的所有成员变量所占内存之和应该为8的倍数
  例3: char a[3]; char b[8]; 因为a最邻近的b是char类型,虽然它是一个8字节的数组,a仍然是按照char类型的大小(1字节)进行对齐,a和它之前的所有成员变量所占内存之和应该为1的倍数
  例4: int a; char b; 虽然a邻近的b是char类型,但由于a本身为int类型,自身类型大小大于b,因此仍然是按int类型大小(4字节)进行对齐
   | 
 
练习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   | struct Demo1{     char c; 	long long b; 	char name[7]; 	char id[3];	 	long long a; }; // 占用内存大小为40,:8 + 8 + 7 + 3 + 6 + 8 = 40
  struct Demo2{     long long a;     char c;     char c1[2];     char c2[14];     int b; }; // 所占内存大小为 32: 8 + 1 + 2 + 14 + 3 + 4 = 32
  struct Demo3{     char a[3];     char b[8]; }; // 所占内存大小为 11:3 + 8 = 11;
  struct Demo4{     char a[3];     int b;     char c;     long long d; } // 所占内存大小为24 :3 + 1 + 4 + 1 + 7 + 8 = 24
  struct Demo5{     long long a;     int b;     char c; }; // 所占内存大小为16 :8 + 4 + 4 = 16
  | 
 
空结构体(类)
如果是一个空结构体或类,则其所占内存大小为1。
测试
虚函数
- 虚函数的原理是系统初始化一个虚函数表,在类中通过一个指向虚函数表的指针来定位虚函数,因此虽然普通成员函数不占用空间,但申明虚函数会占用一个指针的空间,即8字节;
 
- 但无论一个类中有多少个虚函数,这些虚函数都会存放在一个虚函数表中,即只有一个虚函数指针,因此总共只会占用8字节
 
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
   | class Demo1{     char c; 	long long b; 	char name[7];     virtual void func1();     virtual void func2(); }; // 占用内存大小为 32: 8 + 8 + 7 + 1 + 8 = 32 // 其中7变成8是根据虚函数指针的大小,而不是b大小,Demo2可以证明
  class Demo2{     char c; 	int b; 	char name[3];     virtual void func1();     virtual void func2(); }; // 占用内存大小为 24: 4 + 4 + 3 + 5 + 8 = 24 // 且无论虚函数写在什么位置,其进行内存计算的位置都是Demo2这样,Demo3可以证明
  class Demo2{     virtual void func1();     virtual void func2();     char c;     int b;     char name[3];    };
  | 
 
继承
- 继承父类,相当于继承了父类的所有成员,不管是否可见
 
- 根据1,可知子类的大小为继承的父类大小之和,且会根据父类的最后一个元素进行对齐
 
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | class Base{ 	char arr[10]; 	int b; 	virtual void func(); }; // Base:10 + 2 + 4 + 8 = 24 class A:Base{ 	char a[3]; }; // A :24 + 3 + 5 = 32,因为最后一个虚指针是8字节,因此a要跟它对齐 class B:Base{ 	char b[6]; }; // B: 24 + 6 +2 = 32 class C:A,B{ 	 }; // C:32 + 32 = 64
  |