友元 解決運算子過載引數順序問題

2021-10-20 11:35:22 字數 4006 閱讀 1302

友元模板類重的友元函式過載運算子

**舉例:複數類的加號過載

#include

#include

using

namespace std;

class

complex

intrealshow()

intimagshow()

void

printc()

complex operator+(

const complex &);

friend complex operator+(

int)

; complex sum

(const complex &);

complex operator+(

int)

;bool

operator

==(complex)

; complex operator++(

);complex operator++(

int);~

complex()

;}; complex complex::

operator++(

)complex complex::

operator++(

int)

bool complex::

operator

==(complex c)

complex complex::

operator

+(complex &c)

complex complex::

operator

+(conplex &c)

complex complex::

sum(

int c)

complex complex::

operator+(

int c)

測試:

int

main()

由測試函式可知,將sum()的函式名替換為operator+就是運算子的過載,第乙個運算數通過this指標隱式呼叫,a+b實質上是

a.operator+(b),要注意的是,形參使用的是運算數的引用傳遞,使用const,避免修改資料,節約值傳遞的時間,但是返回值不能使用引用傳遞,對區域性變數使用引用傳遞,變數生命結束後,找不到他的值。

運算子過載也有乙個問題,例如operator+(int),複數與實數相加,只能複數在前,因為過載的加號是複數類的成員函式,這要求我們對其進行修改使實數在前也能進行加法,使用友元可以有效解決這一問題。

關於友元,包含友元類、友元函式,友元類是通過在類中新增friend class another_classname的形式,使其他類能夠訪問其私有成員,雖然這一定程度上破壞了類的封裝性,但在一些情況下可以有效節約**量。這裡著重提友元函式

在物件導向程式設計中,友元函式(friend function)是乙個指定類(class)的「朋友」,該函式被允許訪問該類中private、protected、public的資料成員。普通的函式並不能訪問這些資料,然而宣告乙個函式成為乙個類的友元函式則被允許訪問這些資料。

友元函式的宣告可以放在類宣告的任何地方,不受訪問限定關鍵字private、protected、public的限制。

a類的成員函式作為b類的友元函式時,必須先定義a類,而不僅僅是宣告它。

注意:將其他類的成員函式申明為本類的友元函式後,該友元函式並不能變成本類的成員函式。也就是說,朋友並不能變成家人。

我們通過友元函式來實現非成員函式對+的過載,輸入兩個運算數變數,(成員函式不能顯式地傳遞自己)

class

complex

complex operator

+(complex &c,

int x)

《如果使用正常的(類內函式)過載方式,有兩個引數,乙個是隱式的複數類變數,另乙個是ostream的輸出函式ostream &cout,那麼應該是c《友元函式返回值型別:void
class

complex

void

operator

<<

(ostream &os,

const complex &c)

operator《是complex的友元,它訪問了complex的私有成員,但它並非ostream的友元,它將os這個物件作為整體使用,並未訪問ostream的私有與保護成員,c應該為引用傳遞,訪問的應該是c本身而非他的複製

但是void返回會帶來乙個問題,《要求左邊是ostream型別的物件,上面**中的友元會使下面語句出錯,不能連續輸出

cout<1
友元函式返回值型別:ostream
class

complex

ostream &

operator

<<

(ostream &os,

const complex &c)

返回值為os的引用,仍為ostream型別的物件

使用模板類與例項類有區別,一定要注意的兩個點

1。友元函式一定要在類之前宣告,否則找不到函式,會報錯;原因是在編譯時,模板類生成兩次,一次是類頭,另一次是例項化,而友元函式是全域性函式,使第一次生成時找不到函式,因此需要在類描述前進行生命

2. 友元函式在類中宣告時,因為在類之前已經模板宣告了一次,因此在類中的宣告需要在()前加**< t >**,否則也會報錯,實現時不需要加

以順序棧的《過載為例,部分**如下

#include

#include

using

namespace std;

const

int stackincrease =20;

template

<

class

t>

class

seqstack;*

*template

<

class

t> ostream &

operator

<<

(ostream &os,

const seqstack

&s);

//1.友元函式一定要提前宣告**

template

<

class

t>

class

seqstack

~seqstack()

void

push

(const t &x)

;//壓棧

bool

pop(t &x)

;//出棧 ,棧頂元素用x返回

bool

gettop

(t &x)

const

;//得到棧頂元素,x返回

bool

isempty()

const

//判空

bool

isfull()

const

//判滿

intgetsize()

const

//棧元素數

void

makeempty()

//清空棧**

friend ostream &

operator

<<

(ostream &os,

const seqstack

&s);

//2.過載輸出 一定要加否則就不是模板函式**};

template

<

class

t> ostream &

operator

<<

(ostream &os,

const seqstack

&s)

友元運算子過載

運算子就是一種特殊的函式 運算子過載可以是普通函式 const money operator const money a1,const money a2 可以是成員函式 const money operator const money a2 const 當二元運算子作為成員函式進行過載時,只有乙個引...

運算子過載,友元函式

運算子過載 include using namespace std class cint cint const cint timp public cint operator const cint timp const cint add const cint timp const cint add c...

運算子過載與友元

參考 c primer plus 第六版 先給段 include include using namespace std class time void addmin int m void addhr int h void reset int h 0,int m 0 time sum const t...