外观
07.对象的构造顺序、对象的销毁、神秘的临时对象、关于析构的疑问、关于const对象的疑问、关于类成员的疑问
约 1762 字大约 6 分钟
C++对象的构造销毁析构const对象
2022-06-15
二十一、对象的构造顺序
1、问题:C++中的类可以定义多个对象,那么对象构造的顺序是怎样的?
2、对象的构造顺序一
对于局部对象
当程序执行流到达对象的定义语句时进行构造
- 对象定义→构造
下面程序中的对象构造顺序是什么

实例分析:局部对象的构造顺序



3、对象的构造顺序二
对于堆对象
- 当程序执行流到达new语句时创建对象
- 使用new创建对象将自动触发构造函数的调用
- 下面程序中的对象构造顺序是什么?

编程实验:堆对象的构造顺序


4、对象的构造顺序三
对于全局对象
- 对象的构造顺序是不确定的
- 不同的编译器使用不同的规则确定构造顺序
实例分析:全局对象的构造顺序





5、小结
- 局部对象的构造顺序依赖于程序的执行流
- 堆对象的构造顺序依赖于new的使用顺序
- 全局对象的构造顺序是不确定的
二十二、对象的销毁
1、对象的销毁
- 生活中的对象都是被初始化后才上市的
- 生活中的对象被销毁前会做一些清理工作
- 问题:C++中如何清理需要销毁的对象?
- 一般而言,需要销毁的对象都应该做清理
- 解决方案
- 为每个类都提供一个public 的 free函数
- 对象不再需要时立即调用free函数进行清理
2、实例分析:IntArray使用分析
3、存在的问题
- free只是一个普通的函数,必须显示的调用
- 对象销毁前没有做清理,很可能造成资源泄漏
- C++编译器是否能够自动调用某个特殊的函数进行对象的清理?
4、析构函数
C++的类中可以定义一个特殊的清理函数
- 这个特殊的清理函数叫做析构函数
- 析构函数的功能与构造函数相反
定义:~ClassName()
- 析构函数没有参数也没有返回值类型声明(只能有一个析构函数)
- 析构函数在对象销毁时自动被调用
5、编程实验:析构函数使用初探


6、编程实验:IntArray类的进化


7、析构函数的定义准则
当类中自定义了构造函数,并且构造函数中使用了系统资源(如:内存申请,文件打开,等) ,则需要自定义析构函数。
8、小结
- 析构函数是对象销毁时进行清理的特殊函数
- 析构函数在对象销毁时自动被调用
- 析构函数是对象释放系统资源的保障
二十四、经典问题解析二
1、关于析构的疑问
当程序中存在多个对象的时候,如何确定这些对象的析构顺序?
单个对象创建时构造函数的调用顺序
- 调用父类的构造过程(后续课程中讲解)
- 调用成员变量的构造函数(调用顺序与声明顺序相同)
- 调用类自身的构造函数
- 析构函数与对应构造函数的调用顺序相反。
多个对象析构时
- 析构顺序与构造顺序相反
ps:忘记 成员变量的构造函数 和 类自身的构造函数是啥意思了,看下面示例

2、实例分析:构造与析构顺序

3、关于析构的答案
- 对于栈对象和全局对象,类似于入栈与出栈的顺序,最后构造的对象被最先析构!!
- 堆对象的析构发生在使用delete的时候,与delete的使用顺序相关!!
4、关于const 对象的疑问
- const关键字能否修饰类的对象?如果可以,有什么特性?
- const关键字能够修饰对象
- const修饰的对象为只读对象
- 只读对象的成员变量不允许被改变
- 只读对象是编译阶段的概念,运行时无效
5、C++中的const成员函数
- const 对象只能调用const的成员函数
- const成员函数中只能调用const成员函数
- const成员函数中不能直接改写成员变量的值
6、const成员函数的定义

7、编程实验:类的const函数初探

8、关于类成员的疑问
成员函数和成员变量都是隶属于具体对象的吗?
每个具体对象都有自己独立的一套成员变量
所有对象共享一套成员函数(代码段是不可以随意添加和删除的)
从面向对象的角度
- 对象由属性(成员变量)和方法(成员函数)构成
从程序运行的角度
- 对象由数据和函数构成
- 数据可以位于栈,堆和全局数据区
- 函数只能位于代码段(代码段是只读的,当编译器把最终的可执行程序编译好了之后,代码段就固定了;程序运行时不可以改变)
- 对象由数据和函数构成
结论
- 每一个对象拥有自己独立的属性(成员变量)
- 所有的对象共享类的方法(成员函数)
- 方法能够直接访问对象的属性
- 方法中的隐藏参数 this 用于指代当前对象(在类的成员函数中,有个隐含的参数this,是个指针,并且指针的值就是调用这个函数所对应的对象的地址)
9、编程实验:成员函数的秘密


Test::Test(const Test& t)
{
mi = t.mi;
}可以直接访问private区域的数据吗?
成员函数只有一套,成员函数可以直接访问对应类的成员变量。
10、小结
- 对象的析构顺序与构造顺序相反
- const 关键字能够修饰对象,得到只读对象
- 只读对象只能调用const成员函数
- 所有对象共享类的成员函数
- 隐藏的this指针用于表示当前对象
