创建类时编译器自动生成以下成员函数(如果用户没有定义):
1、默认构造函数
2、拷贝构造函数
3、赋值操作符
4、默认析构函数
5、地址操作符
以下一一说明:
构造函数
构造函数在创建对象时被调用。
在用户没有提供构造函数时,编译器将创建一个默认构造函数,这个构造函数不接受任何参数,也不执行任何操作,使类的值在初始化的时候是未知的。
用户创建的构造函数在所有参数都有默认值的情况下也是默认构造函数。
只有在构造函数上才能使用初始化列表,可以用初始化列表初始化const常量成员的值。
拷贝构造函数
拷贝构造函数用于初始化过程中。
拷贝构造函数不能重载,它有固定的参数。
1、每当程序产生对象副本的时候,编译器就会使用拷贝构造函数,如:函数按值传递对象时;函数返回对象时。
2、编译器产生临时对象时也会使用拷贝构造函数,具体时机因编译器不同而异。
默认的拷贝构造函数复制每一个非静态成员的值。若成员本身就是一个类对象,则使用该类的拷贝构造函数。
深拷贝与浅拷贝:
浅拷贝:一些类成员是使用new初始化的、指向数据的指针,默认的拷贝构造函数只会复制数据本身的值,这会导致拷贝之后的对象中同一指针指向相同的地址,在析构函数中使用 delete 时会发生错误。
深拷贝:用户自己定义的显式的拷贝构造函数,复制一个指针引用的数据结构的一个副本,并将副本的地址赋给新对象的成员。
赋值操作符
将已有对象赋给另一个对象时,使用赋值操作符。另外:初始化对象时使用 = 符号不一定会使用赋值操作符,但是一定会使用拷贝构造函数。
默认的赋值操作符接受并返回一个类对象的引用。
赋值操作符的功能与拷贝构造函数类似,同时也有浅拷贝和深拷贝的问题。
在解决深拷贝的问题时,要注意以下几点:
1、因为接受赋值的对象可能有以前分配了的数据,所以要先delete一遍。
2、用this指针检查并避免自我复制。(否则会导致上一步delete错误)
3、函数要返回一个指向调用对象的引用,即*this。
特别注意:赋值操作不会产生新的对象。
析构函数
无参数,不能重载。
在对象过期时调用。分为以下几种情况:
1、如果创建的是静态存储类对象,程序结束时调用。
2、如果创建的是自动存储类对象,在执行完代码块时被调用。
3、如果通过new创建的对象,对象会驻留在堆中,使用delete释放内存时调用。
4、如果创建的是临时对象,在结束对该临时对象的使用时调用。
地址操作符
默认的地址操作符返回this指针。