文章目录
- 一、类的6个默认成员函数
- 二、构造函数
- 1、概念
- 2、构造函数只初始化自定义类型
- 3、对于不会初始化内置类型的补丁
- 4、构造函数优点
- 三、析构函数
- 1、概念
- 2、什么时候需要自己写析构函数 ?
- 3、构造和析构顺序差异
- 四、拷贝构造函数
- 1、概念
- 2、拷贝构造下传值会无限递归
- 3、什么时候需要自己写拷贝构造函数 ?
- 4、拷贝构造优点
一、类的6个默认成员函数
如果一个类中什么成员都没有,简称为空类。空类中并不是什么都没有,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
默认成员函数:
用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
二、构造函数
1、概念
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有一个合适的初始值,并且在对象整个生命周期内只调用一次。
构造函数特性:
1.函数名与类名相同
2.无返回值
3.对象实例化时编译器自动调用对应的构造函数
4.构造函数可以重载
2、构造函数只初始化自定义类型
C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int/char……,自定义类型就是我们使用class/struct/union等自己定义的类型,就会发现编译器生成默认的构造函数会对自定类型成员调用的它的默认成员函数。注意:有些编译器会对自定义类型进行处理,仅仅为个性化行为,在这里我们默认当作编译器不会处理
当我们写的默认构造函数重载时,如果一个无参,一个带参给了缺省值,就会出问题.同时,只要你手写了默认构造,就不会调用编译器生成的默认构造函数
3、对于不会初始化内置类型的补丁
C++11中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时,可以给默认值,当自己没有写默认构造函数的时候,就用缺省值
小结:
1、一般情况下,有内置类型成员,需要自己写构造函数
2、若成员全是自定义类型,可以让编译器自己生成构造函数
4、构造函数优点
优点:
1、构造函数可以确保对象在创建时被正确初始化。对象的创建时机就是在调用构造函数的时候,因此调用构造函数可以保证对象的正确性。
2、构造函数提供了一种方便的方式来初始化对象的成员变量。
3、构造函数还可以在对象被创建时执行初始化操作,例如为对象分配内存等。
4、如果类中有多个构造函数,可以通过不同的构造函数来初始化对象不同的成员变量。这样可以提供更多的灵活性和选择性,在满足不同需求的情况下方便地创建对象
三、析构函数
1、概念
与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作
析构函数特征:
1.析构函数名是在类名前加上字符~
2.无参数无返回值类型
3.一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
4.对象生命周期结束时,C++编译系统系统自动调用析构函数
2、什么时候需要自己写析构函数 ?
对于内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可。如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数。有资源申请时,一定要自己手写,否则会造成资源泄漏,比如Stack类、Queue类
3、构造和析构顺序差异
.构造顺序是按照语句的顺序进行构造,对象析构要在生存作用域结束的时候才进行析构,即对象析构顺序和栈类似,后面构造的对象反而先析构
下面给一个例题便于大家理解:
小结:
析构函数是一个特殊的成员函数,它负责对象被销毁时释放它所占用的内存。当一个对象的生命周期结束时,系统会自动调用它的析构函数,从而避免内存泄漏等问题,这样就不用手动管理内存,减少了代码的复杂度和出错的可能性。
四、拷贝构造函数
1、概念
拷贝构造函数:
拷贝构造函数也是特殊的成员函数,只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。
2、拷贝构造下传值会无限递归
C++规定,内置类型直接拷贝,自定义类型需要调用它的拷贝构造完成拷贝
特征:
1、拷贝构造函数是构造函数的一个重载形式
2.拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用
递归如下,先调用 d 1 d_1 d1的拷贝构造来初始化形参date,变成了Date date( d 1 d_1 d1),仔细一看,和原来调用的Date d 2 ( d 1 ) d_2(d_1) d2(d1)形式一模一样,接下来又会调用 d 1 d_1 d1的拷贝构造来初始形参date,依次死循环下去。对此,我们形参必须用引用接收
3、什么时候需要自己写拷贝构造函数 ?
与构造函数不同,若未显式定义,编译器会生成默认的拷贝构造函数。这里编译器也会拷贝内置类型,,默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝
既然编译器默认生成的和我们自己实现的拷贝构造函数都能完成拷贝功能,那是不是就不需要我们手动实现了呢?
类中如果没有涉及资源申请时,拷贝构造函数写不写都可以,一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝,会造成内存泄漏
浅拷贝问题:
1、析构两次,报错
2、一个修改会影响另─个
对此我们要自己完成深拷贝
深拷贝引用场景:
1、使用已存在对象创建新对象
2、函数参数类型为类类型对象
3、函数返回值类型为类类型对象
4、拷贝构造优点
C++拷贝构造函数是一种特殊的构造函数,用于创建新对象时,将现有对象的值复制到新对象中。
优点:
1、方便复制对象:使用拷贝构造函数可以方便地将一个对象复制到另一个对象。
2、可以避免浅拷贝带来的问题:拷贝构造函数可以确保在进行对象复制时,不会发生深浅拷贝带来的问题,而是通过实现深拷贝,从而避免这类问题的出现。
3、传递对象时更安全:对于传递对象的情况,使用拷贝构造函数可以确保目标对象拥有正确的值,在不确定操作的时候可以避免因为对象值的不确定性出现的错误。
4、可以在对象中实现资源管理:有时候对象中包含有资源(如内存、文件句柄等),拷贝构造函数可以确保正确复制资源。
总结:
下一篇博客,我们将学习赋值运算符重载,并模拟实现一个日期类,期待我们下一篇博客见面就!!!