1.为什么要用到运算符的重载
所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能.
看下面这个代码:怎样实现虚数的加减。
- <pre code_snippet_id="2491281" snippet_file_name="blog_20170720_1_6836729" name="code" class="cpp">#include <iostream>
- using namespace std;
-
- class array{
- public:
- array();
- array(int arr[]);
- array operator + (const array a)const;
- void display()const;
- private:
- int m_arr[5];
- };
-
- array :: array()
- {
- for (int i = 0; i < 5; i++)
- {
- m_arr[i] = 0;
- }
- }
-
- array :: array(int arr[])
- {
- for (int i = 0; i < 5; i++)
- {
- m_arr[i] = arr[i];
- }
- }
-
- array array :: operator + (const array a)const
- {
- array b;
- for (int i = 0; i < 5; i++)
- {
- b.m_arr[i] = this->m_arr[i] + a.m_arr[i];
- }
- return b;
- }
-
- void array :: display()const
- {
- for (int i = 0; i < 5; i++)
- {
- cout<<m_arr[i]<<" ";
- }
- }
-
- int main()
- {
- int a[5] = {1, 2, 3, 4, 5};
- int b[5] = {1, 2, 3, 4, 5};
- array obja(a);
- array objb(b);
- array objc;
- objc = obja + objb;
- objc.display();
-
- return 0;
- }</pre><br>
- <pre></pre>
- 运算符重载的格式为:
返回值类型 operator 运算符名称(形参列表)
{
//函数体
}
operator是关键字,专门用于定义重载运算符的函数。将operator 运算符名称这一部分看做函数名,对于上面的代码,函数名就是operator+。
运算符重载函数除了函数名有特定的格式,其它地方和普通函数并没有区别。
上面的例子中,我们在 array类中重载了运算符+,该重载只对 array对象有效。当执行
- objc = obja + objb;<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">语句时,编译器检测到+号左边(+号具有左结合性,所以先检测左边)是一个 array 对象,就会调用成员函数operator+(),也就是转换为下面的形式:</span>
- objc = obja.operator+ objb
- <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">obja 是要调用函数的对象,objb 是函数的实参。</span>
2.并不是所有的运算符都能够重载
能够重载的运算符包括:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- , ->* -> () [] new new[] delete delete[]
上述运算符中,[]是下标运算符,()是函数调用运算符。自增自减运算符的前置和后置形式都可以重载。
长度运算符sizeof、条件运算符: ?、成员选择符.和域解析运算符::不能被重载。
3.重载不能改变运算符的优先级和结合性
例如:c4 = c1 + c2 * c3;
等价于:
c4 = c1 + ( c2 * c3 );
乘法的优先级仍然高于加法,并且它们仍然是二元运算符。
4.重载不会改变运算符的用法,原有有几个操作数、操作数在左边还是在右边,这些都不会改变。例如~号右边只有一个操作数,+号总是出现在两个操作数之间,重载后也必须如此。
5.运算符重载函数既可以作为类的成员函数,也可以作为全局函数。
6.箭头运算符->、下标运算符[ ]、函数调用运算符( )、赋值运算符=只能以成员函数的形式重载。
举个例子吧:下面这个重载自加运算符的代码
- #include <iostream>
- #include <iomanip>
- using namespace std;
-
- class watch{
- public:
- watch():m_min(0), m_sec(0){}
- void setzero();
- watch run();
- watch operator ++ ();
- watch operator ++ (int n);
- friend ostream & operator << (ostream &, const watch &);
- private:
- int m_min;
- int m_sec;
- };
-
- void watch :: setzero()
- {
- m_min = 0;
- m_sec = 0;
- }
-
- watch watch :: run()
- {
- ++m_sec;
- if (60 == m_sec)
- {
- m_min++;
- m_sec = 0;
- }
- return *this;
- }
-
- watch watch :: operator ++ ()
- {
- return run();
- }
-
- watch watch :: operator ++ (int n)
- {
- watch t = *this;
- run();
- return t;
- }
-
- ostream & operator << (ostream & out, const watch & t)
- {
- out<<setfill('0')<<setw(2)<<t.m_min<<":"<<setw(2)<<t.m_sec;
- return out;
- }
-
- int main()
- {
-
- watch t1, t2;
-
- t1 = t2++;
- cout<<"t1:"<<t1<<endl;
- cout<<"t2:"<<t2<<endl;
- t1.setzero();
- t2.setzero();
-
- t1 = ++t2;
- cout<<"t1:"<<t1<<endl;
- cout<<"t2:"<<t2<<endl;
- t1.setzero();
- t2.setzero();
-
- return 0;
- }
运行结果:
t1:00:00
t2:00:01
t1:00:01
t2:00:01