運算子過載中的隱式轉換問題

2021-08-04 10:51:14 字數 1671 閱讀 6378

譚浩強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...