運算子過載

2021-10-07 05:13:19 字數 3879 閱讀 6572

運算子過載實質上是函式的過載,作用於c++基本資料型別的運算子本來就是函式,我們是過載這些函式,不是只給某字元賦予一些功能。

我們過載運算子,可以改變運算子原本運算元的型別(運算元其實就是函式引數),但不能改變運算元的個數,以及運算子的優先順序。也就是說不能像我們平時過載函式時那麼隨便。

單目運算子我們過載時只能傳乙個引數,雙目只能傳兩個。注意成員函式自帶乙個引數——this指標。

有些運算子可以過載為成員函式,也可以過載為普通函式,也可以過載為友元函式。好像有個規律,運算元順序是,有this指標就是this指標指向的物件為左運算元,另乙個引數為右運算元;不過載為成員函式的話(沒有this指標)就是第乙個引數為左運算元,第二個為右運算元,但這樣不能隨意訪問私有變數,寫成友元更好。

一、過載+和-運算子

注意過載的時候要保證參與運算的兩個物件,不發生改變。其實可以定義成const函式。

class

complex

complex operator

+(complex& b)

;//"+"過載為成員函式

friend complex operator

-(complex& b)

;"-"過載為友員函式

}complex complex::

operator

+(complex& b)

complex operator

-(complex& b)

complex r1(1

,2),

r2(3,

3);r1+r2;

//就是r1.operator+(r2)

r1-r2;

//就是operator-(r1,r2)

有兩個問題:

1、為什麼過載+,-返回值型別是 complex而不是complex&

2、什麼情況下只能過載為友元函式。

首先第乙個問題在return時,會建立乙個新物件,作為和。如果返回新物件的引用,「+」函式結束之後就退出了,新物件也沒了,何來引用呢。

如果我們如果我們希望1+r1能執行的話,就只能過載為友元函式

complex operator+(

int x,complex& b)

這就是上面說的引數順序與運算子運算元的對應關係,complex& b在前,1+r1就是要報錯。

二、賦值運算子過載。

賦值運算子只能過載為成員函式,返回值型別為引用,詳見另一篇文章。

類中有乙個預設賦值運算子,有指標懸掛問題。

三、流插入和提取運算子的過載

1、過載為成員函式

<< 的過載

class

complex

ostream&

operator

<<

(ostream& os);}

ostream& complex::

operator

<<

(ostream& os)

complex r(1

,2);

r<「>>」的過載

class

complex

istream&

operator

>>

(istream& os);}

istream& complex::

operator

<<

(istream& is)

complex r(1

,1);

r>>cin;

所以》也不要過載為成員函式。

2、過載為友員函式

可以把 ostream& 或 istream& 放在 complex& 前面,這樣就可以這樣了

cout>r1;
因為返回值是引用,還可以

cout>r1>>r2;
過載為普通函式與過載為友元函式一樣,只是有無法訪問私有成員變數的缺陷。

四、自增自減運算子的過載。

自增自減運算子都是單目運算子,但有前置和後置之分。也有表示式中的區別之分後置運算子是以運算前的值參與表示式運算的,過載時一定要考慮到這一點。c++規定,前置的++、–作為一元運算子過載;後置的++、–作為二元運算子過載(多寫乙個沒用的int 型)

class

complex

complex&

operator++(

);//前置自增的過載

complex operator--(

int)

;//後置自減的過載

}complex& complex::

operator++(

)complex complex::

operator--(

int)

五、()與[ ]的過載。

過載()被稱為函式物件,是雙目運算子 。物件呼叫它時像函式一樣。

[ ]被成為下標運算子,是雙目運算子,後乙個運算元為整型,表示下標。

class

complex

double

operator()(

int id)

;//前置自增的過載

}double complex::

operator()(

int id)

complex r(1

,2);

cout<1)

//輸出r.real

六、型別轉換運算子的過載

1、不能對型別轉換運算子過載函式指定返回值型別(返回值型別已經由過載的運算子型別決定)。

2、作用是將該類強制型別轉換成我們需要的型別

3、自己定義的型別也可以過載,(即a中過載了b就可以將a型別強制轉換成b型別)

4、explicit關鍵字放在過載函式前,可以禁止編譯器隱式呼叫我的過載函式。

例1:int的過載

class

aoperator

int(

)const

//型別轉換運算子的過載不指定返回值};

intmain()

在main函式中std::cout << a;進行了隱式型別轉換。很多時候這些轉換是另人迷惑的,想禁止的話就在前面加上explicit

explicit

operator

int(

)const

這樣一來就只能顯示型別轉換了

std::cout << a;

//錯誤

std::cout <<

(int

)a;//正確

例2:自定義型別b的過載

classb}

;class

aexplicit

operatorb(

)const};

intmain()

總結:

1、不能定義新運算子

2、過載後符合自然,執行連續使用,加括號不會有bug。這要求考慮返回引用還是本身型別。

3、過載不能改變優先順序和運算元(引數個數)

4、"."、「.*」、「::」、「?:」、「sizeof」不允許過載。

5、()、[ ] 、->、=必須過載為成員函式。

6、單引數建構函式,型別轉換的過載,都會涉及到隱性型別轉換,用explicit禁止隱式,只能顯式。這是很提倡的做法,因為隱式轉換很討厭。

運算子過載之過載型別運算子

普通型別 類型別 呼叫對應的只有乙個引數 引數的型別就是這個普通型別 的建構函式 需求 boy boy1 10000 薪資 建構函式boy int boy boy2 rock 姓名 建構函式boy char 普通型別賦值給類型別其實很簡單,就是專門的對這個賦值的型別定義乙個建構函式。編譯器在執行 的...

運算子過載 賦值運算子的過載

有時候希望賦值運算子兩邊的型別可以不匹配,比如,把乙個int型別變數賦值給乙個complex物件,或把乙個 char 型別的字串賦值給乙個字串物件,此時就需要過載賦值運算子 注意 賦值運算子 只能過載為成員函式 賦值運算子過載例項示例 include include using namespace ...

運算子過載

c 中的運算子 1。大多數系統預定義運算子都能過載 不值得過載 不能被過載 2過載不能改變優先順序 不能改變結合性 不能改變運算子所需運算元的個數 過載後,可按這些運算子的表達方式使用 運算子過載的語法 一 通過運算子過載函式進行過載 1。運算子過載函式是成員函式 語法形式 type x opera...