C 主題 轉換函式

2021-06-22 14:19:37 字數 1565 閱讀 6662

出處

c++主題——轉換函式 

轉換函式的基本規則:

轉換函式只能是成員函式,無返回值,空引數。

不能定義到void的轉換,也不允許轉換成陣列或者函式型別。

轉換常定義為const形式,原因是它並不改變資料成員的值。

轉換函式所引出的問題:

轉換操作符過於強大,它可以定義到一種內建型別的轉換,然而這種內建型別本身是可能繼續轉換成其他的內建型別的(不能轉換到乙個自定義型別後再轉換到另乙個自定義型別),如 operator int() const 定義了到int型的轉換,然後int型可以轉換到float、double、long等型別, 這樣極不容易確定編譯器為我們做了什麼,在出現問題後,也極不容易定位錯誤。

當類型別定義了乙個到基本型別a的轉換後,他可能在實際中轉換到另一基本型別b,這時如果再定義乙個到基本型別c的轉換,而c也可以轉換到b。這樣,就會在實際運用中產生二義性,如a為int,b為long double,c為double,在產生自定義型別的物件時,需要轉換,就會使得編譯器並不知道如何處理,到底是呼叫哪個轉換。

使用自定義轉換時,有兩個潛在的缺陷:1.定義轉換多,會像上述那樣引發二義性;2.一些轉換利大於弊。避免前者的方法是,最好在定義到內建型別的轉換時,只定義乙個(內建型別之間的轉換太靈活了)。避免後者的除了經驗和反覆思考沒什麼好辦法。

《more effective c++》建議將轉換函式設計成一種astype()的函式形式,就像std::string中的成員函式c_str一樣,提供乙個函式,而不是乙個轉換。

轉換函式引出的擴充套件問題:

建構函式也會在標準型別到類型別的轉換中起到意想不到的負面影響。當在某處需要乙個類物件時,他會隱式呼叫建構函式完成轉換,而當已經存在乙個單引數建構函式接受了一種內建型別完成構造,又定義了乙個單引數建構函式接受不同內建型別完成構造時,也會出現和轉換函式相同的問題——二義性。

建構函式和轉換函式之間也可能存在二義性。如:

class

integer;

integer a1,a2;

integer a3 

=a1 

+a2;

inti 

=a3 +1

;//error

這時,int  i = a3 + 1;該如何做?是把a3轉化成int做+運算?還是把1轉換成integer做operator+運算?

如果定義了到算術內建操作符的轉換,就不要在定義接受算術型別的操作符的過載版本。如果使用者需要使用這些操作符,則轉換操作將轉換你所定義的型別物件,然後可以使用內建操作符。

解決這個衝突的乙個比較簡單的方法是把integer的建構函式宣告成顯示的explicit。

另一種比較複雜的方法是在integer內部做乙個proxy class**類,把integer的建構函式的引數宣告成這個**類而不是int。然後讓這個**類做乙個建構函式接受乙個int的型別。這樣在需要a型別的隱式轉換時,要先用int的值構造乙個**型別,然後再由integer建構函式構造乙個物件完成轉換,這是不被允許的,兩層的使用者自定義型別間的轉換編譯器不支援,所以可以起到避免隱式轉換的作用。

(關於proxy class,可以看《more effective c++》的條款30,那裡有精彩的介紹)

C 初級主題 6 賦值函式

賦值語句其實是對 進行過載。test operator const test t 賦值語句的寫法必須是上述形式嗎,答案是否定的。1.為什麼傳參方式是傳引用?test test t test t1 10 test t2 下式進行改寫 t2 t1 如果採用傳值方式,用t1初始化形參時,會呼叫拷貝建構函式...

C 轉換函式

在c 中,可以利用建構函式將乙個int型變數轉換為乙個類物件,如cmyclass aclass 5 有人便會問,可以進行相反的轉換嗎?例如將乙個類物件轉換為乙個int值,int ntemp aclass c 可以實現這一需求.但不是建構函式.建構函式只能用於某種型別到類型別的轉換.要進行相反的轉換,...

C 轉換函式

轉換函式分為兩種 1 自己定義的類通過轉換函式轉換為其他型別 2 其他型別通過轉換函式 類建構函式 轉換為自己定義的類 形式 1 operator typename 條件 轉換函式必須為類方法 轉換函式不能指定返回型別 轉換函式不能有引數 例子 define conv fun h include s...