有關C++中類類型轉換操作符總結(必看篇)。本站提示廣大學習愛好者:(有關C++中類類型轉換操作符總結(必看篇))文章只能為提供參考,不一定能成為您想要的結果。以下是有關C++中類類型轉換操作符總結(必看篇)正文
實例如下:
class SmallInt { public: SmallInt(int i = 0): val(i) { if (i < 0 || i > 255) throw std::out_of_range("Bad SmallInt initializer"); } operator int() const { return val; } private: std::size_t val; };
轉換函數采用如下通用方式:
operator type();
type表示內置類型名、類類型名或由類型別名定義的名字。對任何可作為函數前往類型的類型(除了 void 之外)都可以定義轉換函數。普通而言,不允許轉換為數組或函數類型,轉換為指針類型(數據和函數指針)以及援用類型是可以的。轉換函數必需是成員函數,不能指定前往類型,並且形參表必需為空。operator int 前往一個 int 值;假如定義 operator Sales_item,它將前往一個 Sales_item 對象,諸如此類。轉換函數普通不應該改動被轉換的對象。因而,轉換操作符通常應定義為 const 成員。
SmallInt si;
double dval;
si >= dval // si converted to int and then convert todouble
優點:類類型轉換能夠是完成和運用類的一個益處。經過為 SmallInt 定義到int 的轉換,可以更容易完成和運用 SmallInt 類。int 轉換使 SmallInt 的用戶可以對 SmallInt 對象運用一切算術和關系操作符,而且,用戶可以平安編寫將 SmallInt 和其他算術類型混合運用的表達式。定義一個轉換操作符就能替代定義 48個(或更多)重載操作符,類完成者的任務就復雜多了。
缺陷:二義性
class SmallInt { public: SmallInt(int= 0); SmallInt(double); //Usually it is unwise to define conversions to multiple arithmetic types operatorint() const { return val; } operatordouble() const { return val; } private: std::size_tval; }; void compute(int); void fp_compute(double); void extended_compute(long double); SmallInt si; compute(si); // SmallInt::operator int() const fp_compute(si); // SmallInt::operator double() const extended_compute(si); // error: ambiguous
對 extended_compute 的調用有二義性。可以運用任一轉換函數,但每個都必需跟上一個規范轉換來取得 long double,因而,沒有一個轉換比其他的更好,調器具有二義性。
假如兩個轉換操作符都可用在一個調用中,而且在轉換函數之後存在規范轉換,則依據該規范轉換的類別選擇最佳婚配。若無最佳婚配,就會呈現二義性。
再比方:
能夠存在兩個轉換操作符,也能夠存在兩個結構函數可以用來將一個值轉換為目的類型。
思索 manip 函數,它承受一個 SmallInt 類型的實參:
void manip(const SmallInt &); double d; int i; long l; manip(d); // ok: use SmallInt(double) to convert theargument manip(i); // ok: use SmallInt(int) to convert theargument manip(l); // error: ambiguous
第三個調器具有二義性。沒有結構函數完全婚配於 long。運用每一個結構函
數之前都需求對實參停止轉換:
1. 規范轉換(從 long 到double)後跟 SmallInt(double)。
2. 規范轉換(從 long 到int)後跟 SmallInt(int)。
這些轉換序列是不能區別的,所以該調器具有二義性。
當兩個類定義了互相轉換時,很能夠存在二義性:
class Integral; class SmallInt { public: SmallInt(Integral);// convert from Integral to SmallInt }; class Integral { public: operatorSmallInt() const; // convert from Integral to SmallInt }; void compute(SmallInt); Integral int_val; compute(int_val); // error: ambiguous
實參 int_val 可以用兩種不同方式轉換為 SmallInt 對象,編譯器可以使
用承受 Integral 對象的結構函數,也可以運用將 Integral 對象轉換為
SmallInt 對象的 Integral 轉換操作。由於這兩個函數沒有高低之分,所以這
個調用會出錯。
在這種狀況下,不能用顯式類型轉換來處理二義性——顯式類型轉換自身既可以運用轉換操作又可以運用結構函數,相反,需求顯式調用轉換操作符或結構函數:
compute(int_val.operator SmallInt()); // ok: useconversion operator compute(SmallInt(int_val)); // ok: use SmallInt constructor
改動結構函數以承受 const Integral 援用:
class SmallInt { public: SmallInt(constIntegral&); };
則對compute(int_val) 的調用不再有二義性!緣由在於運用 SmallInt結構函數需求將一個援用綁定到 int_val,而運用 Integral 類的轉換操作符可以防止這個額定的步驟。這一小小區別足以使我們傾向於運用轉換操作符。
顯式強迫轉換消弭二義性
class SmallInt { public: // Usually it is unwise to define conversions tomultiple arithmetic types operatorint() const { return val; } operatordouble() const { return val; } // ... private: std::size_tval; }; void compute(int); void compute(double); void compute(long double); SmallInt si; compute(si); // error: ambiguous
可以應用顯式強迫轉換來消弭二義性:
compute(static_cast<int>(si)); // ok: convertand call compute(int)
顯式結構函數調用消弭二義性
class SmallInt { public: SmallInt(int= 0); }; class Integral { public: Integral(int= 0); }; void manip(const Integral&); void manip(const SmallInt&); manip(10); // error: ambiguous
可以用顯示結構函數消弭二義性:
manip(SmallInt(10)); // ok: call manip(SmallInt) manip(Integral(10)); // ok: call manip(Integral)
規范轉換優於類類型轉換
class LongDouble { public: LongDouble(double ); //… }; void calc( int ); void calc( LongDouble ); double dval; calc( dval ); // which function
最佳可行函數是voidcalc(int), 調用此函數的轉換為:將實參double類型轉換為int類型的,為規范轉換;調用voidcalc( LongDouble)函數時,將實參從double轉換為LongDouble類型,為類類型轉換,由於規范轉換優於類類型轉換,所以第一個函數為最佳可行函數。
以上這篇有關C++中類類型轉換操作符總結(必看篇)就是分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持。