class smallint
operator int() const
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
operatordouble() const
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 ;
class integral ;
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 ;
則對compute(int_val) 的呼叫不再有二義性!原因在於使用 smallint建構函式需要將乙個引用繫結到 int_val,而使用 integral 類的轉換操作符可以避免這個額外的步驟。這一小小區別足以使我們傾向於使用轉換操作符。
顯式強制轉換消除二義性
class smallint
operatordouble() const
// ...
private:
std::size_tval;
};void compute(int);
void compute(double);
void compute(long double);
smallint si;
compute(si); // error: ambiguous
可以利用顯式強制轉換來消除二義性:
compute(static_cast(si)); // ok: convertand call compute(int)
顯式構造函式呼叫消除二義性
class smallint ;
class integral ;
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 中型別轉換操作符
在c語言中,型別轉換只需要在變數前加上轉換的型別即可,而且轉換可以是雙向的,但是這種粗暴的型別對付基本型別還可以,對付複雜型別就力不從心了。因此c 提供了四種型別轉換操作符 static cast dynamic cast const cast reinterpret 1 static cast s...
C 類的操作符過載 型別轉換
這裡總結一下c 裡面類的操作符的過載以及型別轉換的定義,作為對c primer plus第11章的總結。通過操作符過載,可以直接定義兩個型別之間的操作符 加減乘除等 乙個例子是 class vector vector a,b vector c a b 在vector上使用加法運算子操作符過載有兩種實...
C 型別轉換操作符 cast operator
dynamic cast 用以轉換多型型別 polymorphic type 建立執行時檢查將保證轉換的有效性。如果該轉換不是安全的,則丟擲乙個bad cast異常。static cast 用以轉換非多型型別。沒有執行時檢查。const cast 用以除去乙個物件的常態 constness 和易失態...