一。默认成员函数
默认成员函数就是用户没有显示实现,编译器会自动生成的成员函数。
1.构造函数
(1)概念:特殊的成员函数,它的主要任务是对象实例化时初始化对象。构造函数的本质就是替代Init函数的功能。
(2)特点:
- 函数名与类名相同
- 无返回值(也不需要写void)
- 对象实例化时系统会自动调用对应的构造函数
- 构造函数可以重载
- 如果没有显示定义构造函数,则编译器会自动生成一个无参的默认构造函数,一旦用户显示定义,编译器将不会生成
- 无参构造函数,全缺省构造函数,我们不写构造时编译器默认生成的构造函数,都叫做默认构造函数。但它们之中只能同时存在一个。总结一个就是不传实参就可以调用的构造就叫默认构造
- 编译器默认生成的构造,对内置类型成员变量是否初始化是不确定的,看编译器。对于自定义成员变量,要求调用这个成员变量的默认构造函数初始化,如果没有,编译报错。



2.析构函数
(1)概念:特殊的成员函数,它的主要任务是完成对象中资源的清理释放工作,类似于Stack实现的Destroy功能。
(2)特点:
- 析构函数名是在类名前加上字符 ~
- 无参无返回值(也不需要加void)
- 一个类只能有一个析构函数。若没有显示定义,编译器会自动生成默认的析构函数
- 对象生命周期结束时,系统会自动调用析构函数
- 编译器会自动生成默认的析构函数对内置类型成员不做处理,自定义类型成员会调用它的析构函数

3.拷贝构造函数
(1)概念:如果一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数也叫拷贝构造函数。
(2)特点:
- 拷贝构造函数是构造函数的一个重载
- 拷贝构造函数的第一个参数必须是类类型对象的引用,使用传值方式编译器会报错,因为逻辑上会引发无穷递归调用。拷贝构造函数也可以有多个参数,但是第一个参数必须是类类型对象的引用,后面的参数必须有缺省值。
- 自定义类型对象进行拷贝行为时必须调用拷贝构造
- 若没有显示定义拷贝构造,编译器会自动生成拷贝构造函数。自动生成的拷贝构造对内置类型成员变量只会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的拷贝构造
- 如果一个类显示实现了析构并释放了资源,那么他就需要显示写拷贝构造,否则就不需要
- 传引用返回可以减少拷贝,但是一定要确保返回对象在当前函数结束后还在,才能用引用返回
4.运算符重载
(1)作用:允许我们通过运算符重载的形式指定新的含义(即实现同类对象之间的互相赋值)
(2)特点:
- 他的名字是由 operator 和后面要定义的运算符共同构成。他也具有返回类型和参数列表及函数体
- 参数个数和该运算符作用的运算对象数量一样多。一元运算符有一个参数,二元有两个,二元运算符的左侧运算对象传给第一个参数,右侧运算对象传给第二个参数
- 若重载运算符函数是成员函数,则他的第一个运算对象默认传给隐式的 this 指针。
5.赋值运算符重载
(1)定义 : 一个默认的成员函数,用于完成两个已经存在的对象直接的拷贝赋值。拷贝构造用于一个对象拷贝初始化另一个要创建的对象
(2)特点 :
它是一个运算符重载,规定必须重载为成员函数。参数建议写成const类型引用
有返回值,建议写成当前类类型的引用,引用是为了提高效率,有返回值是为了支持连续赋值场景(从右往左依次赋值)
没有显示实现时,编译器会自动生成一个默认赋值运算符重载,这个跟默认拷贝构造函数类似,对内置类型成员变量会完成浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的赋值重载函数
如果一个类显示实现了析构函数并释放了资源,那么他就要显示写赋值运算符重载,否则不需要
(3)不能重载的运算符: .(点),:: ,?: 三目运算符,sizeof,.*
(4)补充说明 :
赋值运算符只能作为类的成员函数
重载的赋值运算只有一个显示形参(本类对象),第一个隐藏参数是this指针
前置++的成员函数原型--->A&operator++(),等价调用--->a.operator()
后置++的成员函数原型--->A operator++(int),等价调用--->a.operator++(0)
6.取地址运算符重载
(1)const成员函数 : 将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后面
说明 : const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
只要不改变调用对象的函数都建议加const