关于对象的数据成员,请读者记住下述两个结论:
本文引用自作者编写的下述图书; 本文允许以个人学习、教学等目的引用、讲授或转载,但需要注明原作者"海洋饼干叔
叔";本文不允许以纸质及电子出版为目的进行抄摘或改编。
1.《Python编程基础及应用》,陈波,刘慧君,高等教育出版社。免费授课视频 Python编程基础及应用
2.《Python编程基础及应用实验教程》, 陈波,熊心志,张全和,刘慧君,赵恒军,高等教育出版社Python编程基础及应用实验教程
3. 《简明C及C++语言教程》,陈波,待出版书稿。免费授课视频
下述C++程序通过对一个Person对象的解析,来说明一个Person类型的对象是如何由其他子对象来构成,以及这些子对象是如何存储在一个Person对象的内部的。
1 //Project - PersonMemory
2 #include <iostream>
3 #include <stdio.h>
4 using namespace std;
5 ... //...表示代码有省略
6 class Person{
7 public:
8 string sName; //姓名
9 string sID; //身份证号
10 GenderType gender; //性别
11 int iWeight; //体重,以克为单位
12 ...
13 }; //注意末尾的分号不能少
14
15 int main(){
16 printf("sizeof(Person) = sizeof(string) x 2 + sizeof(GenderType) "
17 "+ sizeof(int)\n= %lld x 2 + %lld + %lld \n= %lld\n",
18 sizeof(string),sizeof(GenderType),sizeof(int),sizeof(Person));
19
20 Person a("3604020001", "Peter Lee");
21
22 printf("&a = %p, sizeof(a) = %lld\n",
23 &a, sizeof(a));
24 printf("&a.sName = %p, sizeof(a.sName) = %lld\n",
25 &a.sName, sizeof(a.sName));
26 printf("&a.sID = %p, sizeof(a.sID) = %lld\n",
27 &a.sID, sizeof(a.sID));
28 printf("&a.gender = %p, sizeof(a.gender) = %lld\n",
29 &a.gender, sizeof(a.gender));
30 printf("&a.iWeight = %p, sizeof(iWeight) = %lld\n",
31 &a.iWeight, sizeof(a.iWeight));
32
33 return 0;
34 }
上述程序的执行结果为:
1 sizeof(Person) = sizeof(string) x 2 + sizeof(GenderType) + sizeof(int)
2 = 32 x 2 + 4 + 4
3 = 72
4 Person::Person(), sName = Peter Lee
5 &a = 000000000062fd60, sizeof(a) = 72
6 &a.sName = 000000000062fd60, sizeof(a.sName) = 32
7 &a.sID = 000000000062fd80, sizeof(a.sID) = 32
8 &a.gender = 000000000062fda0, sizeof(a.gender) = 4
9 &a.iWeight = 000000000062fda4, sizeof(iWeight) = 4
说明:在读者的计算机上,执行结果中的地址很可能与本书不同。此外,不同的编译器下,string类型的大小,GenderType类型的大小也可能与本书不同。
🚩第6 ~ 13行:一个Person类型的对象,依次包含sName、sID、gender及iWeight共4个数据成员,其类型分别为string、string、GenderType和int。
🚩第16 ~ 18行:打印Person、string、GenderType及int类型的字节数。执行结果的第1 ~ 3行证实,一个Person对象的大小正好等于两个string对象、1个GenderType对象及1个int对象的大小之和。即对象的尺寸等于构成该对象的全部子对象尺寸之和。
🚩第20行:定义Person类型的对象a,构造函数Person::Person()被执行,对a进行了初始化。
🚩第22 ~ 31行:打印了a的全部数据成员的地址及大小。根据输出结果,我们绘制了对象a的内存结构,见图13-2。

如图13-2所示,Person类型的对象a占据了从0x0062fd60开始的连续72个字节的空间。由于a属于自动变量,因此,其内存空间位于栈内。a的4个数据成员按定义顺序依次排列在这72个字节的空间内,其中,sName和sID各占32个字节,gender占4个字节,iWeight占4个字节。
如第5章所述,string类型的对象尺寸是固定的(如本例中的32个字节),但却可以存储几乎长度不限的字符串。其秘密在于:
从图13-2可见,a.sName,a.sID的实际字符串事实上并不在对象内部,而是在堆里。在作者的计算机上,sizeof(Person)以及sizeof(a)均为固定的72个字节,不论a.sName以及a.sID所包含的字符串实际有多长。也就是说,使用sizeof操作符获得的对象尺寸不包含对象动态创建的部分。
为了帮助更多的年轻朋友们学好编程,作者在B站上开了两门免费的网课,一门零基础讲Python,一门零基础C和C++一起学,拿走不谢!
如果你觉得纸质书看起来更顺手,目前Python有两本,C和C++在出版过程中。