运算符重载
运算符重载
- 将运算符看作是一种特殊的函数(操作数是函数的参数,运算结果是函数的返回值)
- 运算符重载现象(移位运算符>>和<<,用作流输入和输出运算符)
重载的运算符
- 定义重载运算符和定义普通函数类似(函数名由关键字operator 和其后要定义的运算符组成:operator=, operator<<, operator+)
- 返回类型:运算结果的类型
- 参数表:提供参与运算的操作数(参数个数取决于运算符的操作数个数和运算符函数是成员函数还是非成员函数)
- 函数体:进行运算,返回运算结果,即表达式的值
类的成员运算符函数
- this 指向的对象被作为运算符的第一个操作数(左)
- 一元运算符函数不需要提供参数
- 二元运算符提供一个参数作为右操作数
非成员运算符函数
- 一元运算符要提供一个类类型的参数
- 二元运算符需要提供两个参数分别作为左、右操作数,其中至少一个参数必须是类类型的(通常声明为类的友元,以便访问私有数据成员)
类X的二元运算符“+”(算术加)
//X的成员运算符函数operator+()类外定义
X X::operator+(const X& right){...}
//X的非成员运算符函数operator+()
X operator+(const X& left, const X& right){...}
类X的一元运算符“!”(逻辑非)
//X的成员运算符函数operator!()类外定义
bool X::operator!(){...}
//X的非成员运算符函数operator!()
bool operator!(const X& oprand){...}
运算符函数
- 运算符函数只有在类类型的对象参与运算时才起作用(当运算符作用于内置类型的运算对象时,不会改变该运算符原来的含义)
- 将运算符作用于类型正确的实参时,会引起重载运算符的调用
- 只有至少一个操作数是用户自定义类型时,才可能调用重载的运算符
- 运算符重载不会改变内置类型的表达式中运算符的含义
常用的运算符重载
- 如果类执行I/O 操作,可以定义移位运算符>>和<<
- 如果类的某个操作是检查相等性,则定义operator==;这时候通常也应该有operator!=
- 如果类包含内在的单序比较操作,则定义operator<;此时也应该有其他关系操作
注:重载运算符的返回类型通常情况下应该与内置版本的返回类型兼容
定义运算符函数时选择成员还是非成员?
- 赋值(=)、下标([])、函数调用(())和成员函数访问箭头(->)运算符必须是成员函数(赋值运算符只能用成员函数重载,复合赋值运算符可以用成员或非成员重载)
- 改变对象状态的运算符或者与给定类型密切相关的运算符,如自增、自减和解引用运算符,通常应该是成员
- 具有对称性的运算符可能转换两个操作数中的任何一个,如算术、关系和位运算符等,通常应该是非成员函数<