今天看到這麼一道題:
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的過載。逗號運算子過載需要乙個引數,並且返回自身類。逗號運算子在複製操作中比較常見,下面就是以賦值操作為例的逗號運算子過...