重载操作符
一、重载操作符的定义
1.重载操作符函数由返回值类型、函数名(operator后接需要定义的操作符)、形参组成;
2.重载操作符必须具有至少一个类类型或枚举类型的操作数;
3.除了函数调用操作符operator()之外,重载操作符使用默认实参是非法的;
4.最好不要重载&&、||、逗号、取地址操作符,因为他们不再具备短路求值特性;
5.大多数重载操作符可定义为类的成员函数和普通成员函数;
- 作为类成员的重载函数,其形参看起来比普通重载函数的形参少一个,因为类成员函数有一个隐含的this指针形参,限定为第一操作数;
- 赋值(=)、下标(【】)、调用(())和成员访问箭头(->)等操作符必须定义为类的成员。
- 改变对象状态或给定类型紧密联系的其他操作符,如自增、自减和解引用,通常定义为类成员函数;
6。操作符重载作为普通成员函数时,通常需要将其设置为所操作类的友元函数;
二、操作符重载的实现
1.输出操作符<<重载
- 为了与IO标准库一致,操作符应接受ostream&作为第一个形参,对类类型const对象的引用作为都第二个参数,并返回对ostream形参的引用;
- ostream&为非const因为输入到流会改变流的状态,该形参是一个引用,因为流对象不能被复制;
- 输出操作符函数必须是非类成员的友元函数;
- ostream& operator<<(ostream& os,const Sales_item& s)
{
os << s.isbn ;
return os;
}
2.输入操作符>>重载
- 为了与IO标准库一致,操作符应接受ostream&作为第一个形参,对类类型const对象的引用作为都第二个参数,并返回对ostream形参的引用;
- ostream&为非const因为输入到流会改变流的状态,该形参是一个引用,因为流对象不能被复制;
- 输出操作符函数必须是非类成员的友元函数;
- 在使用读入的数据前需要检查输入的操作符是否有效;
- ostream& operator>>(ostream& is,const Sales_item& s)
{
is >>s.isbn ;
if(is)
{
}
return is;
}
3.算数操作符+、-、*、\重载
- 算数操作符重载定义为非成员函数;
- 算数操作符重载由于不改变操作数的状态,操作的是对const对象的引用;结果是产生并返回一个新的对象,该对象可初始化为任意一个形参的副本,
- 即定义算数操作符又定义了相关复合操作符的类,一般使用复合复制实现算数操作符;
Sales_item operator+(const Sales_item& lhs,const Sales_item& rhs)
{
Sales_item ret(lhs);
ret+=rhs;
return ret;
}
4.关系操作符==、!=、>、<、<=、>=、重载
- 相等操作符通常比较的是每个数据成员;
- 关系操作符通常定义为非类成员函数;
- 关系操作符重载的返回值类型为bool类型;
bool operator==(const Sales_item& lhs, const Sales_item& rhs)
{
return lhs.sold == rhs.sold &&
lhs.revenue == rhs.revenue;
}
bool operator!=(const Sales_item& lhs, const Sales_item& rhs)
{
return !(lhs == rhs);
}
5.赋值操作符=重载
- 赋值操作符重载必须是类成员;
- 赋值操作符必须返回*this的引用;
Sales_item& Sales_item::operator=(const Sales_item& rhs)
{
sold += rhs.sold;
revenue += rhs.revenue;
return *this;
}
6.下标操作符[]重载
- 下标操作符重载必须是类成员;
- 类定义下标操作符时,一般需要定义两个版本:一个是非const成员并返回引用,另一个是为const成员并返回const引用;
int& Sales_item::operator[](const int index)
{
return data[index];
}
const int& Sales_item::operator[](const int index)const
{
return data[index];
}