運算符重載詳解(二)

3.運算符重載函數作爲類成員函數和友元函數
對運算符重載的函數有兩種處理方式:
<1>把運算符重載的函數作爲類的成員函數
<2>運算符重載函數不是類的成員函數(可以是一個普通函數),在類中把它聲明爲友元函數

例子3:運算符“+”重載函數不作爲成員函數,而放在類外,作爲Complex類的友元函數

class Complex
{
public:
	Complex(){ real = 0, imag = 0; } //定義構造函數
	Complex(double r, double i){ real = r, imag = i; }//構造函數重載
	friend Complex operator + (Complex &c1,Complex &c2); //重載函數爲友元函數
	void display();
private:
	double real;	//實部
	double imag;	//虛部
};
Complex operator + (Complex &c1,Complex &c2)
{
    return Complex(real + c2.real, imag + c2.imag);
}
void Complex::display()
{
	cout << real << "," << imag << "i" << endl;
}
int main()
{
	Complex c1(3, 4), c2(5, -10), c3; 
	c3 = c1 + c2;    //c1 + c2 解釋爲operator + (c1,c2);	
cout << c3.display();
	return 0;
}

備註:
有的C++編譯系統(visual C++ 6.0)沒有完全實現C++標準,它所提供的不帶 .h 的頭文件不支持把運算符重載函數作爲友元函數。若遇到編譯出錯,可以將程序中

#include <iostream>
using namespace std;

改爲

#include <iostream.h>

即可順利運行,以後遇到類似情況,也可照此辦理。

問題:爲什麼將運算符函數作爲友元函數?
因爲運算符函數要訪問Complex類對象中的成員,如果運算符函數不是Complex類的友元函數,而是一個普通函數,它是沒有權利訪問Complex類的私有成員。
問題:什麼情況下用成員函數方式?什麼情況下用友元函數方式?
<1>如果將運算符重載函數作爲成員函數,它可以通過this指針自由地訪問本類的數據成員,因此可以少寫一個函數的參數。但是必須要求表達式中第一個參數(即運算符左側的操作數)是一個對象,而且與運算符函數的類型相同。因此必須同那個類的對象去調用該類的成員函數,而且只有運算符重載函數返回值與該對象同類型,運算結果纔有意義。
<2>如果將運算符重載函數作爲友元函數,如雙目運算符重載爲友元函數,由於友元函數不是類的成員函數,因此在函數的形參列表中必須有兩個參數,不能省略,形參的順序任意,不要求第一個參數必須爲類對象。但在使用運算符的表達式中,要求運算符左側的操作數與函數第1個參數對應,運算符右側的操作數與函數的第2個參數對應。
如:在類Complex中聲明

friend Complex operator + (int &i,Complex &c);

在類外定義友元函數:

Complex operator + (int &i,Complex &c)
{
    return Complex(i + c.real, c.imag);
}

在調用運算符重載函數時

c3 = i + c2; //正確,類型匹配
c3 = c2 + i; //不正確,類型不匹配

數學上的交換律在此不適應。如果希望適用交換律,則應再重載一次運算符“+”,如:

Complex operator + (Complex &c, int &i)
{
    return Complex(i + c.real, c.imag);
}

這樣適用i + c2和c2 + i都合法,編譯系統會根據表達式的形式選擇調用與之匹配的運算符重載函數。可以將以上兩個運算符重載函數都作爲友元函數;也可以將一個運算符重載函數(運算符左側爲對象名的)作爲類的成員函數,另一個(運算符左側不是對象名的)作爲友元函數;但不能將兩個都作爲類的成員函數
究竟用哪個好?
由於友元的使用會破壞類的封裝,從原則上講,要儘量將運算符函數作爲成員函數,以下僅供參考:
<1>C++規定,複製運算符“=”、下標運算符“[]”、函數調用運算符()、成員運算符“->”必須作爲成員函數。
<2>流插入“<<”和流提取運算符“>>”、類型轉換運算符不能定義爲類的成員函數,只能作爲友元函數。
<3>一般將單目運算符和複合運算符(+=,-=,/=,*=,&=,!=,^=,%=,>>=,<<=)重載爲成員函數。
<4>一般將雙目運算符重載爲友元函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章