c++ 重载运算与类型转换
1. 基础概念
重载的运算符是具有特殊名字的函数:(重载运算符函数,运算符函数。重载运算符)
依次包含返回类型,函数名(operator=),参数列表,函数体。
只有重载的函数调用运算符operator()才能有默认实参。
关于参数的数量,一般来说,一元运算符有一个参数,二元有两个,三元有三个;
但是如果该运算符函数是成员函数,则其中一个运算对象将是本类对象,第一个参数隐式绑定到this常量指针上,不显示在参数列表中。成员运算符函数的参数数量比运算符对象少一个。
HasPtr& operator=(const HasPtr& right){ mString = right.mString; return *this; }
运算符函数要么是一个类类型的成员函数,要么它必有类类型的参数。这是因为不能重载内置类型之间的运算(可以重载类类型与类类型之间的运算,类类型和内置类型之间的运算)。
不能自己发明运算符,不能改变运算符的优先级,也不能改变运算符原始运算对象的个数,例如&运算符可以用于一元运算,也可以用于二元运算,则根据参数数量判断是一元还是二元,但是!操作符永远不可能重载为二元运算符。
2. 一个例子
可以先看一个简单的例子,重载了类类型Data的 "+" 二元运算符,该运算符函数不是成员函数,因此,参数为两个类类型,返回的是类类型中string成员的拼接版(中间加入--)
#include <iostream> #include <string> using namespace std; class Data{ public: Data(){} Data(string str){ this->str = str; } string str; }; string operator+(const Data& data1, const Data& data2){ string str = data1.str + " -- " + data2.str; return str; } int main(){ Data data1("hello"), data2("slam"), data3("!!!"); cout << data1+data2+data3 << endl; }
输出:
hello -- slam -- !!!
若希望将操作符函数定义为Data类的成员函数,则需要改动如下:
#include <iostream> #include <string> using namespace std; class Data{ public: Data(){} Data(string str){ this->str = str; } string str; Data operator+(const Data& data); }; // 只有将返回值定义为Data类型,表达式才能使用连续运算的形式data1+data2+data3 Data Data::operator+(const Data& data){ str = str + " -- " + data.str; return *this; } int main(){ Data data1("hello"), data2("slam"), data3("!!!"); cout << (data1+data2+data3).str << endl; }
输出结果相同。
注意在第一个例子中(非成员函数)
data1+data2 等价于 operator+(data1, data2)
第二个例子中(成员函数调用)
data1+data2 等价于 data1.operator+(data2)
3. 常用重载运算符
1) 输入输出运算符 << >>
2) 算数和关系运算符 == != <
3) 赋值运算符 =
4) 下标运算符 []
5) 递增和递减运算符 ++ --
6) 成员访问运算符 * ->
7) 函数调用运算符 ()