1. 程式人生 > >二元運算符重載

二元運算符重載

成員函數重載 spa add dex 個數 mage 沖突 友元 進行

------------------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 &c1const 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】

二元運算符重載