拷贝构造函数
// 基本概念
1. // 系统提供的默认拷贝构造函数,会逐个拷贝成员变量值,但只会进行简单的属性拷贝
2. // 怎样区分到底是拷贝构造函数还是重载等号操作符
1. 区分该操作到底是初始化对象,还是给已经存在的类对象赋值
1. Time t1 = t2; // 用t2初始化t1对象,是拷贝构造函数
2. Time t1; t1 = t2; // 重载等号操作符
3. Time t1 = t2; Time t1(t2); // 2语句完全等价
// 控制是否生成默认的构造函数
Time()=default; // 自动生成默认构造函数,哪怕已经定义了显式构造函数
Time()=delete; // 禁止系统生成这个无参构造函数:Time mytime;定义对象,出错
// 发生拷贝构造函数的场合
1. // 使用一个已经创建完毕的对象来初始化一个新对象
2. // 当函数的形参是类的对象时,调用函数时,进行形参与实参结合时,调用了拷贝构造。这时要在内存新建一个局部对象,并把实参拷贝到新的对象中去。
3. // 当函数的返回值是类对象时,调用拷贝构造函数。它是在函数执行完返回调用者时使用的。理由是要建立一个临时对象,再将该临时对象返回给调用者。因为局部对象在离开建立它的函数时就消亡了,不可能在返回调用函数后继续生存,所以在处理这种情况时,编译器会在调用函数的表达式中创建一个匿名临时对象,该对象的生命周期只在函数调用处的表达式中。所谓return对象,实际上是调用拷贝构造函数把该对象的值拷贝到临时对象中。如果返回的是普通变量,处理过程类似,只是不调用构造拷贝构造函数而已。
// 默认的拷贝构造函数在暗中进行哪些操作
有参构造函数
// 声明默认参数、初始化列表
Time(int h, int m, int s = 30); // 声明默认参数
Time(int h, int m, int s) : Hour(h), Minute(m), Second(s){}
析构函数
1. // 析构函数没有参数,不能有返回值。一个类只能有一个析构函数
2. // 对象销毁时做清理工作的特殊函数,系统自动调用它
3. // 使资源被及时释放
// 析构函数的调用
1. // 当对象销毁时,系统调用析构函数
2. // 当成员变量在栈上开辟空间,对象销毁时会调用默认析构
3. // 当成员变量在堆上开辟空间,必须写一个带free或delete的显式析构函数
4. // 谁最后被构造,谁就最先被析构
、
初始化成员变量举例:类内初始化成员变量
class mytime
{
private:
int hour = 0;
int min = 0;
int sec = 0;
}
初始化成员变量举例:通过构造函数初始化成员变量
class mytime
{
private:
int hour;
int min;
public:
mytime() :hour(0), min(0){} // 无参,设置为0初值
mytime(int h,int m):hour(h),min(m){}// 有参,初始化列表
mytime(int h,int m=0):hour(h),min(m){}// 有参,带默认参数的
mytime(int h,int m,)
{
hour = h;
min = m;
}
};
初始化成员变量举例:委托构造函数辅助初始化成员变量
class mytime
{
private:
int hour;
int min;
public:
mytime(int h,int m):hour(h),min(m){}
mytime():mytime(0,0){}
}// 该无参构造函数的初始化调用了有参构造函数,委托有参构造函数帮且自己初始化
// 委托构造函数:当修改有参的初始化算法时,无参构造函数的初始化算法随之改变
类对象的初始值
1. // 调用有参构造函数时,初始值由参数指定
2. // 调用无参构造函数时,基本类型成员变量的初始值为不确定的