讀者能夠嘗試預言一下這段代碼的輸出:ios
#include <iostream> using namespace std; class Complex { private: double real; double imag; public: // 默認構造器無explicity關鍵字 Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {} // 比較操做符==,接受一個Complex的參數 bool operator == (Complex rhs) { return (real == rhs.real && imag == rhs.imag)? true : false; } }; int main() { // a Complex object Complex com1(3.0, 0.0); if (com1 == 3.0)//將Complex與double類型比較 cout << "Same"; else cout << "Not Same"; return 0; }
輸出:spa
Same
上面Complex的==操做符接受的是一個Complex參數。當程序運行到com1 == 3.0時,程序會自動調用Complex的構造器而且傳入參數3.0,而後獲得一個新的Complex對象,再將這個新對象傳給com1的==操做符。因此程序表面上看起來是Complex和double在進行比較,但實際上程序作了隱式的轉化(將double轉成了Complex),依然是兩個Complex在比較。code
在C++中若是一個類有可以被單參數所調用的構造器,那麼這個構造器就被稱爲轉化構造器——轉化構造器容許從單參數到類構造的轉化。C++中可以接受單參數的構造器默認都是轉化構造器。對象
那麼如何避免這種隱式的轉化呢?能夠使用explicity關鍵字。使用了explicity關鍵字的構造器就不容許上面的隱式轉化,要轉化的話,只能強制轉化。blog
咱們修改後的程序以下:ci
#include <iostream> using namespace std; class Complex { private: double real; double imag; public: // 在構造器上加入explicity關鍵字 explicit Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {} // 比較操做符==,接受一個Complex的參數 bool operator== (Complex rhs) { return (real == rhs.real && imag == rhs.imag)? true : false; } }; int main() { // a Complex object Complex com1(3.0, 0.0); //if (com1 == 3.0)//編譯錯誤 if (com1 == (Complex)3.0) //Complex的構造器使用了explicity關鍵字,就只能進行強制轉化了。 cout << "Same"; else cout << "Not Same"; return 0; }
在案例中,咱們能夠將double轉化爲Complex,可是必需強制轉化。get
下面是一個賦值的案例(Complex的構造器上無 explicity 關鍵字):it
Complex com1(3.0, 0.0); Complex com2 = 3.0;//將一個3.0賦值給Complex對象
第一個語句是傳入參數構造器Complex對象,這沒有什麼可討論的。第二個語句將3.0賦值給了Complex對象,其實原理和上面是同樣的,首先傳入參數3.0到Complex的構造器構造一個臨時Complex對象,而後再將臨時Complex對象傳給com2對象。
若是給Complex構造器加上explicity關鍵字,那麼就變成以下的形式了:io
Complex com2 = (Complex)3.0;
原文連接:編譯