在上一篇中写到,一个类会产生的6种默认函数中的前三个默认函数:
1.构造函数
2.析构函数
3.拷贝构造函数
4.赋值运算符重载
5.取地址操作符重载
6.拷贝构造函数
这次将着重讲解后三个函数。
赋值运算符重载
运算符重载
~什么是运算符重载呢?
~在构造函数中,曾提到过,C++将类型分为自定义类型和内置类型。而对于已经存在的运算符(==、+、-、*…)来说,它们其实只支持内置类型,并不支持自定义类型。那么,如果存在一个日期类型,我们想要比较两个日期是否相等,要怎么办呢?因此就产生了运算符重载这一说法,使用operator将 == 重新定义一种输出方式就好了。
operator
函数原型:返回类型+operator+要重载的操作符+(参数列表)
举个栗子叭:
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1900,int month = 1,int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// bool operator==(Date* this, const Date& d2)
// 这里需要注意的是,左操作数是this指向的调用函数的对象
bool operator == (const Date& d)
//将赋值运算符==重载,即 == 可支持自定义类型的日期类 进行比较是否相等
{
return _year == d._year && _month == d._month && _day == d._day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2019,9,18);
Date d2(2018,9,18);
cout<<(d1 == d2)<<endl;
return 0;
}
下面是可以进行重载的运算符:
下面是不可以进行重载的运算符:
- 成员访问运算符:.
- 成员指针访问运算符:->*, .*
- 域运算符:::
- 长度运算符:sizeof
- 条件运算符:?:
- 预处理运算符:#
要注意的是:
1.不能再去重载除了以上允许的符号以外的符号:例如 operator $;
2.重载运算符必须有一个类类型或者枚举类型的操作数;
3.用于内置类型的操作符,其原意不能改变:即+你可不能重载成减法什么的;
4.作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的
操作符有一个默认的形参this,限定为第一个形参;
赋值运算符
直接上代码!
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1900,int month = 1,int day = 1)
{
_year = year;
_month = month;
_day = day;
}
Date& operator =(const Date& d)
{
if(*this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2019,9,18);
Date d2;
d2 = d1;
return 0;
}
注意:赋值运算符重载有以下四点需要注意:
- 参数类型
- 返回值
- 检测是否自己给自己赋值
- 返回*this
- 一个类如果没有显式定义赋值运算符重载,编译器也会生成一个,完成对象按字节序的值拷贝。
const成员
const修饰的类成员函数实际上修饰的是该函数隐含的this指针,这就表明着,在这个函数中,你无法修改this指针指向的对象。
例如:
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1900,int month = 1,int day = 1)
{
_year = year;
_month = month;
_day = day;
}
//实际上是void display(const Date *this)
void display() const
{
cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2019,9,18);
return 0;
}
对于一个对象来说,它的权限只能被缩小,不能被放大:比如一个对象可读可写,那么它可以被const修饰让它变成只读的;但是一个只读的却不能通过引用或者指针去修改它。
取地址操作符重载
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
例如:
class Date
{
public :
Date* operator&()
{
return this ;
}
const Date* operator&()const
{
return this ;
}
private :
int _year ; // 年
int _month ; // 月
int _day ; // 日
};
注意:这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如希望让别人获取到指定的内容等。