譚浩強c++書中運算子過載隱式轉換關於以下兩句話的問題
friend complex operator+(complex&, complex&);
friend complex operator+(const complex&,const complex &);
1.隱式轉換不會被用於非const的引用引數
2.二義性問題
3.為什麼用友元函式
#include#includeusing namespace std;
class complex
complex(float r)//轉換建構函式
complex(float r, float i) :real(r), imag(i){}
friend complex operator+(complex&, complex&);//沒有二義性
operator double() const
//轉換操作符,必須為成員函式,形參列表為空,,一般不應該改變被轉換的物件,通常定義為
const
//friend complex operator+(const complex&,const complex &)//注釋上邊一句換為此句存在二義性,用顯示轉換消除二義性
void display();
private:
float real;
float imag;
};void complex::display()
complex operator+(complex &c1, complex &c2)
int main()
因為非const的引用只能繫結同型別的物件,const則可以繫結能互相轉換的型別。即隱式轉換不會被用於非const的引用引數。
1)當上述**,形參為非const引用時,i為double型別,要呼叫運算子過載函式,i需要轉換為complex型別引用,那麼就建立了臨時變數,這樣就不能呼叫運算子過載函式了,因此這種情況是c1先呼叫型別轉換函式,使c1變成double型別,然後兩個double型別相加,再呼叫轉換建構函式,使右值變為complex型別,過程為 c3.complex((c1.operator double(c1))+i) 沒有二義性。
2)當使用注釋行,形參為非const引用時,二義性。第一種同上,第二種,先使i轉換為complex型別,然後呼叫過載的+運算子,再賦值給c3,過程為operator+(c1,temp.complex(i)) 看到了二義性。
3)其他地方看到的通俗理解,感覺沒毛病。如果輸入的是const引用,const代表的是「不會被修改」,不會被修改也就等於沒有輸出,因此輸入字元陣列可以轉換為乙個臨時的字串再提供const引用,因為「轉換得到的這個臨時變數在函式退出時直接銷毀就行,不會有任何問題。但如果輸入的不是const引用,那就代表「會被修改」,也就等於有輸出,那麼字元陣列是可以轉換為字串,但這個臨時字串在函式結束後該怎麼辦?你說它沒有意義可以銷毀,你怎麼告訴編譯器?編譯器不知道,它就報錯。
《c++primer中文版第四版》在p435頁有指導原則,這樣說:
io操作符必須為非成員函式。我們不能將該操作符定義為類的成員,否則,左操作符將只能是該類型別的物件。
下標操作符必須為成員函式。
對稱的操作符,如算數操作符/相等操作符/關係操作符/位操作符等,最好定義為普通非成員函式(友元)。
JavaScript運算子中的隱式轉換規律
如果包含的是有效數字字串或者是有效浮點數字串,則會將字串轉換 number 為數值,再進行加減操作,返回值的型別是 number型別。如果不包含有效數字字串,則會將字串的值轉換為nan,返回值的型別是 number型別。如果是boolean型別,則先會把true或者false轉換為1或者0,再進行加...
過載《運算子,以及隱式的型別轉換函式
過載 運算子,以及隱式的型別轉換函式,能達到一樣的效果嗎?隱式的型別轉換函式,可以把物件轉換為其他的型別 比如下例,當使用cout 輸出時,student類隱式的轉化為char 型別,實現了直接輸出的效果。include include include using namespace std cla...
JS隱式轉換 與 運算子
js是弱型別語言,運算時若兩邊資料型別不一樣會自動轉換型別,寫 時不小心就就掉坑里了。看下面面試題 console.log false console.log true console.log true console.log false true console.log true false co...