在一个类中,编译器会自动生成默认的成员函数,当对象进行初始化时,会默认调用这个函数来初始化。
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。
它的特点是:
没有返回值
系统自动调用
构造函数可以重载
名字和类名一致
class Date(){
public:
//全缺省构造函数
Date(int x = 1){};
private:
int year;
};
int main()
{
Date d(1);
return 0;
}
同时,这些默认成员函数,只要用户自己定义了,那么系统将不会进行自动生成了。
当我们一个对象完成任务后,最后还要回收系统,也就是还需要释放空间,销毁对象。对于局部变量的销毁,一般是有编译器完成。但是对象的销毁却是由析构函数来完成的。
同样,析构函数也是默认成员函数,当我们对象结束以后,系统会自动调用来销毁对象。
对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
析构函数的特性:
无参无返回值
对象生命周期结束时,系统自动调用
名字为类名前面加~ 格式为: ~类名(){}
一个类只有一个析构函数,如果用户没有自己定义,则系统会自动生成。同时析构函数不能构成重载
class Date(){
public:
//全缺省构造函数
Date(int x = 1){};
//析构函数自己定义
~Date(){
year = 0;
}
private:
int year;
};
int main()
{
Date d(1);
return 0;
}
在对象的创建过程中,我们有时候会需要将一个对象在复制一份。这时,我们就需要用到拷贝构造函数。
拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存 在的类类型对象创建新对象时由编译器自动调用。
同样,函数也会自动生成拷贝构造函数,完成拷贝工作。
拷贝构造函数的特性:
拷贝构造是构造函数重载的一个形式
拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用。
如果没有显示定义,系统会自动默认生成,自动调用(默认的拷贝构造函数对象按内存存储按 字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。对于开辟空间的数组的拷贝,就只会拷贝数组的地址过去,导致两个变量指向同一片空间,可能会影响后续的操作)
拷贝构造函数典型调用场景:
使用已存在对象创建新对象
函数参数类型为类类型对象
函数返回值类型为类类型对象
一、运算符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其 返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型+ operator+操作符+(参数列表)
需要注意的点:
不能使用operator来创建新的运算符,比如operator@就是错误的
重载操作符必须有一个类类型参数
用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐 藏的this
.* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。
bool operator==(const Date& d1, const Date& d2)
{
return d1._year == d2._year
&& d1._month == d2._month
&& d1._day == d2._day;
}
// bool operator==(Date* this, const Date& d2)
// 这里需要注意的是,左操作数是this,指向调用函数的对象
bool operator==(const Date& d2)
{
return _year == d2._year;
&& _month == d2._month
&& _day == d2._day;
}
二、赋值运算符重载
赋值运算符重载格式
参数类型:const T&,传递引用可以提高传参效率
返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
检测是否自己给自己赋值
返回*this :要复合连续赋值的含义
2.赋值运算符只能重载成类的成员函数不能重载成全局函数
3.用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注 意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符 重载完成赋值。
4.前置++和后置++重载
前置++是先返回++之后的值,因为+1后,值不会改变,能传引用返回,效率更高。
后置++,因为是先返回本身,再+1,因此在实现过程中,需要先创建一个临时对象存储。
// 前置++:返回+1之后的结果
// 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率
Date& operator++()
{
_day += 1;
return *this;
}
// 后置++:
// 前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
// C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器
自动传递
// 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存
一份,然后给this+1
// 而temp是临时对象,因此只能以值的方式返回,不能返回引用
Date operator++(int)
{
Date temp(*this);
_day += 1;
return temp;
}