深入解析C 程式設計中的運算子過載

2022-09-27 02:12:20 字數 3321 閱讀 9194

c++中預定義的運算子的操作物件只能是基本資料型別,實際上,對於很多使用者自定義型別,也需要有類似的運算操作。例如:

class complex

void display();

private:

double real;

double imag;

}; complex a(10,20),b(5,8);

「a+b」運算如何實現?這時候我們需要自己編寫程式來說明「+」在作用於complex類物件時,該實現什麼樣的功能,這就是運算子過載。運算子過載是對已有的運算子賦予多重含義,使同乙個運算子作用於不同型別的資料導致不同型別的行為。

運算子過載的實質是函式過載。在實現過程中,首先把指定的運算表示式轉化為對運算子函式的呼叫,運算物件轉化為運算子函式的實參,然後根據實參的型別來確定需要呼叫達標函式,這個過程愛編譯過程中完成。

一、 運算子過載的規則

運算子過載規則如下:

①、 c++中的運算子除了少數幾個之外,全部可以過載,而且只能過載c++中已有的運算子。

②、 過載之後運算子的優先順序和結合性都不會改變。

③、 運算子過載是針對新型別資料的實際需要,對原有運算子進行適當的改造。一般來說,過載的功能應當與原有功能相類似,不能改變原運算子的操作物件個數,同時至少要有乙個操作物件是自定義型別。

不能過載的運算子只有五個,它們是:成員運算子「.」、指標運算子「*」、作用域運算子「::」、「sizeof」、條件運算子「?:」。

運算子過載形式有兩種,過載為類的成員函式和過載為類的友元函式。

運算子過載為類的成員函式的一般語法形式為:

函式型別 operator 運算子(形參表)

運算子過載為類的友元函式的一般語法形式為:

friend 函式型別 operat 運算子(形參表)

其中,函式型別就是運算結果型別;operator是定義運算子過載函式的關鍵字;運算子是過載的運算子名稱。

當運算子過載為類的成員函式時,函式的引數個數比原來的操作個數要少乙個;當過載為類的友元函式時,引數個數與原運算元個數相同。原因是過載為類的成員函式時,如果某個物件使用過載了的成員函式,自身的資料可以直接訪問,就不需要再放在參數列中進行傳遞,少了的運算元就是該物件本身。而過載為友元函式時,友元函式對某個物件的資料進行操作,就必須通過該物件的名稱來進行,因此使用到的引數都要進行傳遞,運算元www.cppcns.com的個數就不會有變化。

運算子過載的主要優點就是允許改變使用於系統內部的運算子的操作方式,以適應使用者自定義型別的類似運算。

二、 運算子過載為成員函式

對於雙目運算子b,如果要過載b為類的成員函式,使之能夠實現表示式oprd1 b oprd2,其中oprd1為類a的物件,則應當把b過載為a類的成員函式,該函式只有乙個形參,形參的型別是oprd2所屬的型別。經過過載後,表示式oprd1 b oprd2 就相當於函式呼叫oprd1.operator b(oprd2).

對於前置單目運算子u,如「-」(負號)等,如果要過載u為類的成員函式,用來實現表示式u oprd,其中oprd為a類的物件,則u應當過載為a類的成員函式,函式沒有形參。經過過載之後,表示式u oprd相當於函式呼叫oprd.operator u().

對於後置運算子「++」和「- -」,如果要將它們過載為類的成員函式,用來實現表示式oprd++或oprd--,其中oprd為a類的物件,那麼運算子就應當過載為a類的成員函式,這時函式要帶有乙個整型形參。過載之後,表示式oprd++和oprd—就想當於函式呼叫oprd.operator++(0)和oprd.operator—(0);

運算子過載就是賦予已有的運算子多重含義。通過重新定義運算子,使它能夠用於特定類的物件執行特定的功能,這便增強了c++語言的擴充能力。

1. 運算子過載的作用:

運算子過載允許c/c++的運算子在使用者定義型別(類)上擁有乙個使用者定義的意義。過載的運算子是函式呼叫的語法修飾:

class fred;

#if 0

// 沒有算符程式設計客棧過載:

fred add(fred, fred);

fred mul(fred, fred);

fred f(fred a, fred b, fred c)

#else

// 有算符過載:

fred operator+ (fred, fred);

fred operator* (fred, fred);

fred f(fred a, fred b, fred c)

#endif

2. 可以用作過載的運算子:

算術運算子:+,-,*,/,%,++,--;

位操作運算子:&,|,~,^,<<,>>

邏輯運算子:!,&&,||;

比較運算子:<,>,>=,<=,==,!=;

賦值運算子:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;

其他運算子:,(),->,,(逗號運算子),new,delete,new,delete,->*。

下列運算子不允許過載:

.,.*,::,?:

3. 運算子過載後,優先順序和結合性:

使用者過載新定義運算子,不改變原運算子的優先順序和結合性。這就是說,對運算子過載不改變運算子的優先順序和結合性,並且運算子過載後,也不改變運算子的語法結構,即單目運算子只能過載為單目運算子,雙目運算子只能過載雙目運算子。

4. 編譯程式如何選用哪乙個運算子函式:

運算子過載實際是乙個函式,所以運算子的過載實際上是函式的過載。編譯程式對運算子過載的選擇,遵循著函式過載的選擇原則。當遇到不很明顯的運算時,編譯程式將去尋找引數相匹配的運算子函式。

5. 過載運算子有哪些限制:

(1) 不可臆造新的運算子。必須把過載運算子限制在c++語言中已有的運算子範圍內的允許過載的運算子之中。

(2) 過載程式設計客棧運算子堅持4個「不能改變」。

不能改變運算子運算元的個數;

不能改變運算子原有的優先順序;

不能改變運算子原有的結合性;

不能改變運算子原有的語法結構。

6. 運算子過載時必須遵循哪些原則:

運算子過載可以使程式更加簡潔,使表示式更加直觀,增加可讀性。但是,運算子過載使用不宜過多,否則會帶來一定的麻煩。

(1) 過載運算子含義必須清楚。

(2) 過載運算子不能有二義性。

運算子過載函式的兩種形式

運算子過載的函式一般地採用如下兩種形式:成員函式形式和友元函式形式。這兩種形式都可訪問類中的私有成員。

三、例子

使用全域性函式過載

#include

class a

; void print();

void print(){cout<

本文標題: 深入解析c++程式設計中的運算子過載

本文位址:

深入C 的運算子過載

對於簡單的運算子,可以參考之前的博文。之後會有一篇關於從等號運算子過載的角度研究深淺拷貝的博文。這裡是講 逗號,取成員運算子,輸入輸出運算子,下標運算子,括號,new和delete的過載。逗號運算子過載需要乙個引數,並且返回自身類。逗號運算子在複製操作中比較常見,下面就是以賦值操作為例的逗號運算子過...

深入C 的運算子過載

對於簡單的運算子,可以參考之前的博文。之後會有一篇關於從等號運算子過載的角度研究深淺拷貝的博文。逗號運算子過載需要乙個引數,並且返回自身類。逗號運算子在複製操作中比較常見,下面就是以賦值操作為例的逗號運算子過載。include includeusing namespace std class tem...

深入C 的運算子過載

對於簡單的運算子,可以參考之前的博文。之後會有一篇關於從等號運算子過載的角度研究深淺拷貝的博文。這裡是講 逗號,取成員運算子,輸入輸出運算子,下標運算子,括號,new和delete的過載。逗號運算子過載需要乙個引數,並且返回自身類。逗號運算子在複製操作中比較常見,下面就是以賦值操作為例的逗號運算子過...