个人主页:【😊个人主页】
系列专栏:【❤️系列专栏】
文章目录
- 前言
- 构造函数与析构函数
- 构造函数
- 析构函数
- 拷贝构造函数
- 深拷贝
- 浅拷贝
- 浅拷贝和深拷贝的区别
前言
期末复习笔记,感兴趣的可以收藏
构造函数与析构函数
构造函数
C++用以初始化对象的数据成员的函数
构造函数要注意的知识点:
- 构造函数是没有返回值类型的。
- 构造函数的函数名必须 与类名一致。
- 构造函数并不是由我们手动调用的, 构造函数是在创建对应对象的时候由jvm主动调用的(每创建一个对象就会调用一次构造函数)。
- 如果一个类没有显式的添加一个构造函数,那么java编译器会为该类添加一个无参的构造函数。
- 如果一个类已经显式的添加一个构造函数,那么java编译器则不会再为该类添加一个无参的构造函数。
- 构造函数是可以以函数重载的形式存在多个的。
- 构造类型可以设置缺省参数。
- 构造函数不可以对静态数据成员进行初始化
- 编译器总是自动创建一个不带参数的构造函数
构造函数的格式:修饰符 函数名(形式参数列表){初始化的语句;
}
析构函数
析构函数(destructor) 与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。
构造函数要注意的知识点:
- 构造函数可以有多个来构成重载,但析构函数只能有一个,不能构成重载
- 构造函数可以有参数,但析构函数不能有参数
- 与构造函数相同的是,如果没有显式的写出析构函数,那么编译器也会自动加上一个析构函数,什么都不做;如果我们显式的写了析构函数,那么将会覆盖默认的析构函数
- 在主函数中,析构函数的执行在return语句之前,这也说明主函数结束的标志是return,return执行完后主函数也就执行完了,就算return后面还有其他的语句,也不会执行
- 一个类中只能定义一个析构函数
class <类名>
{public:~<类名>();};<类名>::~<类名>(){
//函数体
}
拷贝构造函数
拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。
拷贝构造函数通常用于:
- 通过使用另一个同类型的对象来初始化新创建的对象。
- 复制对象把它作为参数传递给函数。
- 复制对象,并从函数返回这个对象
拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。
使用场景:
- 对象以值传递的方式传入函数参数
- 对象以值传递的方式从函数返回
- 对象需要通过另外一个对象进行初始
常见形式:
classname (const classname &obj) {
// 构造函数的主体
}
深拷贝
只要发现对象有可变类型,就会对该对象到最后一个可变类型的每一层对象进行拷贝,对每一层拷贝的对象都会开辟新的内存空间进行存储
通常包括:
不可变类型: 数字、字符串、元组
对于数字和字符串,都是不可变类型,所以使用深拷贝的时候,不会开辟新的内存空间。
元组中如果有可变类型对象,进行深拷贝后,会开辟新的内存地址。元组中如果没有可变类型对象,进行深拷贝后,不会开辟新的内存地址。
如果发现元组里面有可变类型那么,会对元组进行拷贝和子元素列表进行拷贝,拷贝后都会产生一个新的内存空间。但是不可变类型不会进行拷贝,因为不可变类型不允许在原有内存空间的基础修改数据。所以拷贝没有意义。因为每次拷贝,内存地址都会发生变化。
可变类型: 列表 、 字典、 集合
对应深拷贝来说也会进行拷贝,如果发现子对象也是可变类型也会进行拷贝,拷贝后会开辟新的内存空间存储拷贝后的对象。
浅拷贝
对象复制时,只对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。
只会对可变类型的第一层对象进行拷贝,不会对子对象进行拷贝,拷贝成功后会开辟一个新的内存空间存储拷贝这个对象
通常包括:
1.不可变类型:数字、字符串、元组
浅拷贝不会对不可变类型进行拷贝,也就是说不会开辟内存空间
2.可变类型: 列表 、字典、 集合
对于可变类型来说,浅拷贝只拷贝第一次层,不会对子对象进行拷贝,所以第一层内存地址发生了变化,但是子对象内存地址没有变化
浅拷贝和深拷贝的区别
浅拷贝最多拷贝对象的一层,深拷贝可能是拷贝对象的多层