二元運算符重載
------------------siwuxie095
二元運算符重載
所謂 二元運算符,即 這個符號與兩個操作數進行運算
(1)加號 + 的重載
加號 + 的重載方式有兩種:一種是友元函數重載,一種是成員函數重載
1)先來看成員函數重載,如下:
定義一個坐標類:Coordinate
在類中聲明成員函數 operator+(),它的參數是 const Coordinate &coor
在實現時:
首先需要定義一個臨時對象 temp,傳入對象 coor 的 m_iX 要和
當前對象的 m_iX 相加,賦值給臨時對象 temp 的 m_iX,而對於
m_iY 同理 … 最後將 temp 作為返回值返回出去
在使用時:
定義 3 個 Coordinate 的對象 coor1、coor2、coor3,用 coor3 來
接收 coor1 與 coor2 相加的和,這裏的加號 + 就已經用到了運算符
重載,相當於 coor1.operator+(coor2)
註意:在加號 + 的重載函數 operator+() 的傳入參數 coor2 的前面,
其實有一個隱形參數 this,而 this 就相當於傳入的第一個參數 coor1
2)再來看友元函數重載,如下:
友元函數重載相對於成員函數重載來說,更能說明問題:
通過 friend 聲明將全局函數 operator+() 聲明為友元函數,它的兩個
參數分別為:const Coordinate &c1 和 const Coordinate &c2
其中,const 可寫可不寫,如果寫上,那麽在 operator+() 中就不能再
修改
c1 和 c2 的值了,其實在做加法,即 讓一個數與另一個數相加時,
我們也不希望在加的過程當中去修改加數本身的值
所以,加 const 其實是一種設計上的規範
在實現時:
也需要定義一個臨時對象 temp,傳入參數為 c1 和 c2,c1 的 m_iX
與 c2 的 m_iX 相加,賦值給 temp 的 m_iX,對於 m_iY 同理 … 最後
將 temp 作為返回值返回出去
在使用時:
使用時,其實和成員函數的加號 + 運算符重載是一樣的,仍然要定義
3 個 Coordinate 的對象 coor1、coor2、coor3,將 coor1 與 coor2
相加的和賦值給 coor3,其實就相當於調用 operator+(coor1,coor2)
(2)輸出符號 << 的重載
將輸出符號 << 的重載聲明為友元函數 operator<<(),它的返回值
必須是 ostream&,它的第一個參數也必須是一個 ostream 的引用,
第二個參數是要進行輸出的對象 或引用(引用效率更高)
在實現時:
將 ostream 的對象引用 out 替代原來寫成 cout 的位置,其他寫法不變,
分別輸出 m_iX 和 m_iY 的值,並一定要將 out 作為返回值返回出去
在使用時:
定義一個 Coordinate 的對象 coor,通過 cout 就可以直接輸出 coor 的
m_iX 和 m_iY,如果不進行運算符重載,這樣寫肯定是錯誤的,進行運算
符重載之後,這樣寫就相當於 operator<<(cout,coor)
通過這個例子,從側面也能看出: cout 其實就是一個對象,並且是一個
ostream 類型的對象
那麽,輸出運算符可以采用成員函數進行重載嗎?
從成員函數重載的特點說起:
如果使用成員函數重載,如:上面的加號 + 運算符的重載,傳入的
只有一個參數,這個參數其實是第二個加數,第一個加數默認就是
隱形的 this 指針,即 當前對象
可是,對於輸出運算符來說,第一個參數必須是 ostream 的引用,
這就意味著第一個參數不能是隱形的 this 指針,二者是相沖突的
所以,當重載輸出運算符 << 時,絕對不可以通過成員函數進行
重載,必須使用友元函數進行重載
(3)索引符號 [] 的重載
索引運算符 [] 更多的運用在數組上,這裏先運用到 Coordinate 類中:
在聲明時,將之作為一個成員函數放在類中,定義方法:operator[]()
因為它是索引,所以要傳入一個 int 型的變量作為索引,而返回值
要麽是 m_iX,要麽是 m_iY
在實現時:
判斷傳入的 index 參數:
如果等於 0,就將 m_iX 作為返回值返回出去,如果等於 1,就將 m_iY
作為返回值返回出去,如果是其他值,暫不處理,實際上應該拋出異常
在使用時:
定義一個 Coordinate 的對象 coor,如果通過 cout 輸出 coor 的
0 號元素,即 輸出橫坐標 m_iX,如果輸出 coor 的 1 號元素,即
輸出縱坐標 m_iY
當調用 coor 接索引時,其實就相當於調用 coor.operator[]()
那麽,索引運算符可以采用友元函數進行重載嗎?
答案是否定的,不能采用友元函數進行重載。原因是友元函數重載,
它的第一個參數可以是成員函數重載中的隱形 this 指針,也可以是
其它值
但作為索引運算符來說, 它的第一個參數必須是 this 指針,因為
只有第一個參數是 this 指針,才能夠傳入索引,並使得這個索引
所表達的是當前對象中的數據成員
所以,索引運算符必須采用成員函數進行重載,無法使用友元函數
進行重載
程序:
Coordinate.h:
#ifndef COORDINATE_H #define COORDINATE_H
#include <iostream> using namespace std;
class Coordinate { //+號運算符的友元函數重載 與註釋掉的成員函數重載做對比 //可以給參數加const 畢竟在做加法運算時不希望加數出現變化 friend Coordinate operator+(Coordinate &c1, Coordinate &c2);
//輸出運算符重載只能是友元函數重載 //因為其傳入的第一個參數必須是ostream的一個引用 (引用的名字任意 只要合法) // //而根據成員函數重載的特點 傳入的第一個參數 //是this指針(隱形) 也就是當前對象 二者相沖突 所以只能是友元函數重載 // //第二個參數是要輸出的一個對象或者引用(引用效率更高) //可以加它一個const 即const Coordinate coor; //返回值必須是ostream 加一個引用 & friend ostream &operator<<(ostream &output, Coordinate &coor);
public: Coordinate(int x, int y); //+號運算符的成員函數重載 返回值是一個Coordinate的對象 //第一個參數是當前的對象 也就是隱形的this指針(第一個操作數) //第二個就是這裏明面上的引用(第二個操作數) // //即默認第一個加數是當前對象 第二個加數是傳入的參數 //可以給參數加const 畢竟在做加法運算時不希望加數出現變化 // //Coordinate operator+(Coordinate &c);
//索引運算符只能是成員函數重載 因為友元函數重載的第一個參數 //可以是成員函數重載中的那個this指針 也可以是其他的值 // //但作為索引運算符來說 它的第一個參數必須是this指針 //因為只有第一個參數是this指針 才能夠傳入索引 //才能夠使得這個索引表達的是當前這個對象中的成員 // //在這個例子中 第一個參數一定是this指針 它表達是Coordinate的一個對象 //接下來傳入的0或者是1: //所表達的就是這個傳入的this指針所指向的對象當中的0號元素或者1號元素 //所謂0號元素就是當前對象的X值 所謂1號對象就是當前對象的Y值 //所以只能采用成員函數進行重載 int operator[](int index);
int getX(); int getY(); private: int m_iX; int m_iY; };
#endif |
Coordinate.cpp:
#include "Coordinate.h" #include <ostream>
Coordinate::Coordinate(int x, int y) { m_iX = x; m_iY = y; }
int Coordinate::getX() { return m_iX; }
int Coordinate::getY() { return m_iY; }
//Coordinate Coordinate::operator+(Coordinate &c) //{ // //先定義一個臨時的對象temp 並初始化 // Coordinate temp(0, 0); // //當前對象(即this指針)和傳入的對象橫坐標相加 // temp.m_iX = this->m_iX + c.m_iX; // temp.m_iY = this->m_iY + c.m_iY; // return temp; //} Coordinate operator+(Coordinate &c1, Coordinate &c2) { Coordinate temp(0, 0); temp.m_iX = c1.m_iX + c2.m_iX; temp.m_iY = c1.m_iY + c2.m_iY; return temp; }
//因為使用了ostream類 在頭文件要包含 #include<ostream> ostream &operator<<(ostream &output, Coordinate &coor) { //註意這裏就不需要getX()和getY()了 //因為這裏是友元 可以直接訪問其數據成員 output << coor.m_iX << "," << coor.m_iY; //返回的是ostream類型的對象 return output; }
//註意返回類型是int型 int Coordinate::operator[](int index) { if (0 == index) { return m_iX; } if (1 == index) { return m_iY; } //如果既不是0 也不是1 就應該拋出異常 } |
main.cpp:
#include "stdlib.h" #include "Coordinate.h"
int main(void) { Coordinate coor1(1, 3); Coordinate coor2(2, 4); Coordinate coor3(0, 0); //coor3 = coor1 + coor2;//coor3 = coor1.operator+(coor2); coor3 = coor1 + coor2;//coor3 = operator+(coor1,coor2); cout << coor3.getX() << "," << coor3.getY() << endl;
//operator<<(cout,coor3); //由此可知 cout實際上是一個對象 是一個ostream類型的對象 cout << coor3 << endl;
cout << coor3[0] << endl;//coor.operator[](0); cout << coor3[1] << endl;//coor.operator[](1); system("pause"); return 0; } |
【made by siwuxie095】
二元運算符重載