一、类的6个默认成员函数
在上一篇博客中,我们计算了空类的大小为 1 。那么空类中真的什么东西都没有吗?其实不是的,当一个类在什么都不写的时候就会自动生成6个默认的成员函数(用户没有写,但是编译器自动生成的成员函数)。
接下来我们就将围绕上图展开本篇博客……
二、构造函数——用以对象初始化
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。
特征:
1)函数名与类名相同
2)无返回值(不需要写void)
3)实例化对象时由编译器自动调用
4)可以重载(一般建议写一个全缺省的构造)
5)若类中没有显示定义构造函数,则C++编译器会自动生成一个无参的默认构造函数。
但是,一旦用户显示定义了构造函数,编译器就不会自动生成了
6)内置类型成员变量在类中声明时可以给默认值
7)无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。 注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为 是默认构造函数
三、析构函数——用于对象中资源清理
特性:
1)函数名为在类名前加~
2)无参无返回值
3)一个类有且仅有一个析构函数(不支持函数重载),若未显示定义,则由系统自动生成默认的析构函数
4)对象生命周期结束时,由编译器自动调用析构函数
5) 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如 Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。
那么,什么时候需要我们显示定义构造函数,什么时候又不需要我们显示定义析构函数呢?
需要显示定义情况:有资源需要显示清理时我们需要写析构函数
不需要显式定义情况:a)没有资源需要清理
b)内置类型成员没有资源需要清理,剩下的都是自定义类型成员,自定义类型调用自己的析构函数
四、拷贝构造函数——使用同类对象初始化创建对象
拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存 在的类类型对象创建新对象时由编译器自动调用。
特征:
1)拷贝构造函数也是构造函数的重载形式
2)构造函数的参数有且仅有一个,且必须是类类型对象的引用。传值的话编译器会直接报错。因为会引发无限递归
引发无限递归的原因分析:在传值调用过程中,需要对形参进行拷贝构造,但是并无拷贝构造函数,会引发无限递归,直到程序崩溃
3)若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。浅拷贝不能对资源进行管理,如栈中的数组就没法浅拷贝,必须深拷贝才能完成
总结:
1)如果没有管理资源,一般情况下,不需要写拷贝构造,使用编译器默认生成的即可
2)如果是自定义类型,内置类型成员没有指向资源,默认生成的浅拷贝构造也可以
3)一般情况下,不需要写析构函数就不需要写拷贝构造函数
4)如果内部有指针之类的指向资源,需要显示写析构函数,通常也就需要显示写拷贝构造函数完成深拷贝