先上一個(gè)關(guān)于隱式類型轉(zhuǎn)換的例子
struct Rational1 {
Rational1(int n=0, int d=1):num(n), den(d) {
cout << __func__ << "(" << num << "/" << den << ")" << endl;
}
int num;
int den;
};
struct Rational2 {
explicit Rational2(int n=0, int d=1):num(n), den(d) {
cout << __func__ << "(" << num << "/" << den << ")" << endl;
}
int num;
int den;
};
void Display1(Rational1 r1) {
cout << "Numerator: " << r1.num << " Denominator:" << r1.den << endl;
}
void Display2(Rational2 r2) {
cout << "Numerator: " << r2.num << " Denominator:" << r2.den << endl;
}
int main(){
Rational1 r1_1 = 11; // Rational1(11/1)
Rational1 r1_2(12); // Rational1(12/1)
Rational2 r2_1 = 21; // 無法通過編譯
Rational2 r2_2(22); // Rational2(22/1)
Display1(1); // Rational1(1/1)
Display2(2); // 無法通過編譯
Display2(Rational2(2)); // Rational2(2/1)
return 0;
}
Rational1和Rational2唯一的區(qū)別是構(gòu)造函數(shù)的explicit,如果不聲明explicit,構(gòu)造函數(shù)會(huì)被隱式調(diào)用。雖然Display1編譯成功了,但是如果不結(jié)合Ration1的定義,很容易誤會(huì)成Display1接受一個(gè)整型變量并打印。
在C++11中,標(biāo)準(zhǔn)將explicit的使用范圍擴(kuò)展到了自定義的類型轉(zhuǎn)換操作符上,以支持“顯示類型轉(zhuǎn)換”。explicit關(guān)鍵字作用于類型轉(zhuǎn)換操作符,意味著只有在直接構(gòu)造函數(shù)或顯示類型轉(zhuǎn)換的時(shí)候可以使用該類型。例如:
class ConvertTo {};
class Convertable {
public:
explicit operator ConvertTo() const { return ConvertTo(); }
};
void func(ConvertTo ct) {}
int main(){
Convertable c;
ConvertTo ct(c); //直接初始化,通過
ConvertTo ct2 = c; //拷貝構(gòu)造函數(shù)初始化,編譯失敗
ConvertTo ct3 = static_cast<ConvertTo>(c); //強(qiáng)制轉(zhuǎn)化,通過
func(c); //拷貝構(gòu)造初始化,編譯失敗
return 0;
}
Convertable類中定義了一個(gè)顯示轉(zhuǎn)換到ConvertTo類型的類型轉(zhuǎn)換符。對(duì)于main函數(shù)中,ct是通過直接構(gòu)造函數(shù)初始化,可以編譯通過,ct3是顯示強(qiáng)制轉(zhuǎn)換,編譯通過。而ct2是通過拷貝構(gòu)造函數(shù)初始化,編譯失敗,用函數(shù)func時(shí),傳入Convertable的變量會(huì)導(dǎo)致參數(shù)的拷貝構(gòu)造,編譯不通過。