二元運算符重載

------------------siwuxie095 ios

   

   

   

   

   

   

   

   

二元運算符重載 數組

   

   

所謂 二元運算符,即 這個符號與兩個操做數進行運算 函數

   

   

   

   

   

(1)加號 + 的重載 this

   

   

   

加號 + 的重載方式有兩種:一種是友元函數重載,一種是成員函數重載 spa

   

   

   

1)先來當作員函數重載,以下: 設計

   

定義一個座標類:Coordinate 3d

   

   

   

在類中聲明成員函數 operator+(),它的參數是 const Coordinate &coor 指針

   

   

   

在實現時: 對象

   

   

   

首先須要定義一個臨時對象 temp,傳入對象 coor 的 m_iX 要和 blog

當前對象的 m_iX 相加,賦值給臨時對象 temp 的 m_iX,而對於

m_iY 同理 … 最後將 temp 做爲返回值返回出去

   

   

   

在使用時:

   

   

   

定義 3 個 Coordinate 的對象 coor一、coor二、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 的對象 coor一、coor二、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】

相關文章
相關標籤/搜索