深入理解 運算子的過載

2021-08-20 20:38:20 字數 2992 閱讀 7156

今天看到這麼一道題:

templateclass bignumber

bignumber operator+(bignumber b)

};

已知b1,b2是bignumber的兩個物件,則下列表示式中錯誤的是?

a 3+3

b b1+3

c b1+b2

d3+b1

題幹中的意思不就是類裡面過載了乙個「+」法運算子麼,所以:

a 是正常的算數加法操作 √

c 是呼叫了過載的「+」號運算子,實際執行起來就類似於這樣:b1.operator+(b2) √

經過查資料,分析如下:

1、首先,題幹中的過載運算子是作為類的成員函式的,作為類的成員函式時,如果被過載的運算子是二元運算子的話,運算子過載函式只需要乙個引數,因為另乙個引數是隱含的this指標;

2、加法運算子的結合型是自左向右,所以對於b來講,執行時編譯器發現b1是乙個bignumber的物件,就會去呼叫過載的「+」法運算子,類似於:b1.operator(3),此時的3被強制轉化成bignumber型別;所以c √

3、對於d,執行時,編譯器首先檢查「+」的左邊,發現是乙個普通int型變數,所以就不去呼叫過載的「+」法運算子函式了。但是「+」號右邊又不是乙個基本算數型別,所以,就報錯了。所以 d ×

1、對於上面討論的題目,「+」,結合型從左至右,所以先檢查「+」號左邊是否是乙個bignumber物件,如果是,就執行過載函式,否則,不執行。

所以,結合型在過載時是很重要的,例如:

//秒錶類

class stopwatch

public:

void

setzero()

stopwatch run(); // 執行

stopwatch operator++(); //++i,前置形式 ?

stopwatch operator++(int); //i++,後置形式 ?

friend ostream & operator

<<( ostream &, const stopwatch &);

private:

int m_min; //分鐘

int m_sec; //秒鐘

};

stopwatch operator++();這個是++運算子的前置過載形式,為什麼?因為++運算子的結合型是自右至左,而過載函式無引數。若有以下定義

stopwatch a;

++a; //此時a就作為乙個預設引數,類似於這樣a.operator+();

a++; // ??據說是 強行規定!! -_-!!

我是這麼記憶的:

自右向左檢查,我猜測編譯器自動的給a++補了個零,就變成0a++了,類似於這樣a.operator(0);-_-!!

其實通常情況下,過載++運算子是這樣的:

(1)前置++運算子的過載方式:

成員函式的過載: 函式型別& operator++()

友元函式的過載:friend 函式型別& operator++(類型別& )

(2)後置++運算子的過載方式:

成員函式的過載:函式型別 operator++(int)

友元函式的過載:friend 函式型別 operator++(類型別&, int)

需要注意的一點是,後置++返回的是右值,所以返回型別不要再加&引用了。友元函式的過載和普通函式的過載是一樣的。

(這段參考:

所以++++c合法,而c++++不合法。為什麼?

++過載函式的實現大致是這樣的:

classa& classa::operator++()            //前置++

const classa classa::operator++(int) //後置++

如果要實現c++++合法,必須使後置返回變數或變數的引用。c++是先返回c值再+1,所以不可能返回c,那就只能先建立區域性變數來儲存c的初值,然後再返回區域性變數(區域性變數不允許返回引用),但返回了區域性變數之後,如果再連著進行下一次++運算,參與運算的就是這個區域性變數的值了,所以此時c++++其實等效與c++,也就沒有存在的意義了。

下面我們以全域性函式的形式過載》,使它能夠讀入兩個 double 型別的資料,並分別賦值給複數的實部和虛部:

istream & operator>>(istream &in, complex &a)
istream 表示輸入流,cin 是 istream 類的物件,只不過這個物件是在標準庫中定義的。之所以返回 istream 類物件的引用,是為了能夠連續讀取複數,讓**書寫更加漂亮,例如:

complex c1, c2;

cin >> c1 >> c2;

為什麼我們把istream 型別作為」 operator>> 「函式的第乙個引數?(如果簡單的把operato>> 的兩個引數反過來是會報錯的),因為cin在運算時的結合型是自左相右,在執行cin>>c1時,就類似於:operator>>(cin, c1);

如果我們真想把 operator>> 函式的兩個參考顛倒過來,即:istream & operator>>(complex &a, istream &in),那麼我們在使用cin進行標準輸入時,就只能這樣了:

c1 >> cin;  //只進行單次輸入

c2 >> (c1 >> cin); //進行連續輸入;

對於c1 >> cin; 執行起來類似於這樣的:operator>> (c1, cin);

對於c2 >> (c1 >> cin); 執行起來類似於這樣的:operator>>(c2, (c1 >> cin));

是不是很彆扭?所以呢,別浪,還是老老實實的這麼寫吧:istream & operator>>(istream &in, complex &a)

這一段參考:(

理解運算子的操作

在數學中,運算是一種數 算,它包含零或多個輸入值 稱為運算元 以產生輸出值。常用操作 如加法 使用表示操作的特殊符號 如 這些符號稱為運算子。程式設計人員的工作方式相同,但名稱可能並不總是符號。運營商的工作類似於函式,輸入引數並返回乙個值,但它們更簡明。例如,4 2 3是讀比新增更容易 4,多 2,...

Java 位運算子 深入理解

作用是對運算子兩側以二進位制表達的操作符按位分別進行 與 運算。而這一運算是以數中同樣的位 bit 為單位的。操作的規則是 僅當兩個運算元都為1時。輸出結果才為1。否則為0 示比例如以下 12 的二進位制為 0000 1100.5 的二進位制為 0000 0101.則 12 5 的二進位制為 000...

深入C 的運算子過載

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