關於C 中類型別轉換操作符總結

2021-07-05 23:29:11 字數 3807 閱讀 7510

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 和易失態...