运算符重载
C++为了增强代码的可读性,引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号
函数原型:返回值类型 operator操作符(参数列表)
-
不能通过链接其他符号来创建新的操作符:比如operator@
-
重载操作符必须有一个类类型参数
-
用于内置类型的运算符,其含义不能改变
-
作为类成员函数重载时,其形参看起来比操作数数目少一个,因为成员函数䣌第一个参数为隐藏的this
-
.* :: sizeof ?: .
这五个运算符不能重载 -
*
:可以重载 -
函数重载:可以允许参数不同的同名函数的存在
-
运算符重载:自定义类型可以直接使用运算符
==
全局的operator==
bool operator==(const Date& d1, const Date& d2)
{
return d1._year == d2._year
&& d1._month == d2._month
&& d1._day == d2._day;
}
成员 operator==
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year; _month = month; _day = day;
}
bool operator==(const Date& d2)
{
return _year == d2._year;
&& _month == d2._month
&& _day == d2._day;
}
private:
int _year; int _month; int _day;
};
赋值运算符重载
1. 格式
- 参数类型:const T&,传递引用可以提高传参的效率
- 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
- 检测是否自己给自己赋值
- 返回
*this
:要符合连续赋值的含义
Date& operator=(const Date& d)
{
if(this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
先判断两个参数是否是同一个对象,如果是则直接返回第一个对象,如果不是则将第二个参数的成员变量依次赋值给第一个参数的成员变量,然后返回第一个参数的引用。
2. 赋值运算符只能重载成类的成员函数不能重载成全局函数
赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认值运算符重载冲突了,所以赋值运算符重载只能是类的成员函数。
3. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝
内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。
operator= 我们不写,编译器会生成默认的operator=
根拷贝构造的行为类似,内置类型值拷贝,自定义类型调用它的赋值
<<
cout<<
的自动识别类型的本质是函数重载。
双操作数的运算符,第一个参数是左操作数,第二个参数是右操作数。
其他运算符一般是实现成成员函数,>> <<流运算符必须是实现到全局,这样才能让流对象做第一个参数,才符合可读性。
流本质是为了解决,自定义类型的输入和输出问题。
printf和scanf无法解决自定义类型的输入输出问题。