本文的所有內容均來自http://www.2cto.com/kf/201311/258753.html,感謝此作者:)
今天是第一次聽到C++還有個轉換構造函數,之前經常見到默認構造函數、拷貝構造函數、析構函數,但是從沒聽說過轉換構造函數,隱式轉換函數也是一樣,C++的確是夠博大精深的,再次嘆服!
其實我們已經在C/C++中見到過多次標準類型數據間的轉換方式了,這種形式用于在程序中將一種指定的數據轉換成另一指定的類型,也即是強制轉換,比如:int a = int(1.23),其作用是將1.23轉換為整形1。然而對于用戶自定義的類類型,編譯系統并不知道如何進行轉換,所以需要定義專門的函數來告訴編譯系統改如何轉換,這就是轉換構造函數和類型轉換函數! 一、轉換構造函數 轉換構造函數(conversion constructor function) 的作用是將一個其他類型的數據轉換成一個類的對象? 當一個構造函數只有一個參數,而且該參數又不是本類的const引用時,這種構造函數稱為轉換構造函數。 轉換構造函數是對構造函數的重載。 例如: [cpp] Complex(double r) { real=r; imag=0; } 其作用是將double型的參數r轉換成Complex類的對象,將r作為復數的實部,虛部為0?用戶可以根據需要定義轉換構造函數,在函數體中告訴編譯系統怎樣去進行轉換? 那么如何使用轉換構造函數進行類型轉換呢?我們看如下的例子:[cpp] // TypeSwitch.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; class Complex { public: Complex():real(0),imag(0){}; Complex(double r, double i):real(r),imag(i){}; Complex(double r):real(r),imag(0){}; // 定義轉換構造函數 void PRint(){ cout<<"real = " << real <<" image = "<<imag<<endl; } Complex& Operator+(Complex c){ return Complex(this->real + c.real, this->imag + c.imag); } private: double real; double imag; }; int main(int argc, _TCHAR* argv[]) { Complex c; c = 1.2; // 調用轉換構造函數將1.2轉換為Complex類型 c.Print(); Complex c1(2.9, 4.2); Complex c2 = c1 + 3.1; // 調用轉換構造函數將3.1轉換為Complex類型 c2.Print(); return 0; } 不僅可以將一個標準類型數據轉換成類對象,也可以將另一個類的對象轉換成轉換構造函數所在的類對象?如可以將一個學生類對象轉換為教師類對象,可以在Teacher類中寫出下面的轉換構造函數:[cpp] Teacher(Student& s) { num=s.num; strcpy(name,s.name); sex=s.sex; } 使用方法同上! 注意: 1.用轉換構造函數可以將一個指定類型的數據轉換為類的對象?但是不能反過來將一個類的對象轉換為一個其他類型的數據(例如將一個Complex類對象轉換成double類型數據)? 2.如果不想讓轉換構造函數生效,也就是拒絕其它類型通過轉換構造函數轉換為本類型,可以在轉換構造函數前面加上explicit!例如:[cpp] // TypeSwitch.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; class Complex { public: Complex():real(0),imag(0){}; Complex(double r, double i):real(r),imag(i){}; explicit Complex(double r):real(r),imag(0){}; // explicit禁止構造函數的轉換功能 void Print(){ cout<<"real = " << real <<" image = "<<imag<<endl; } private: double real; double imag; }; int main(int argc, _TCHAR* argv[]) { Complex c1(1.2, 2.3), c2; double d; d = c1 + 1.1; // 調用類型轉換函數將c1轉換為double,編譯出錯! cout<<d<<endl; return 0; } 二、類型轉換函數 用轉換構造函數可以將一個指定類型的數據轉換為類的對象?但是不能反過來將一個類的對象轉換為一個其他類型的數據(例如將一個Complex類對象轉換成double類型數據)?而類型轉換函數就是專門用來解決這個問題的!類型轉換函數的作用是將一個類的對象轉換成另一類型的數據? 如果已聲明了一個Complex類,可以在Complex類中這樣定義類型轉換函數:[cpp] operator double( ) { return real; } 類型轉換函數的一般形式為: operator 類型名( ) { 實現轉換的語句 } 注意事項: 1.在函數名前面不能指定函數類型,函數沒有參數? 2.其返回值的類型是由函數名中指定的類型名來確定的? 3.類型轉換函數只能作為成員函數,因為轉換的主體是本類的對象,不能作為友元函數或普通函數? 4.從函數形式可以看到,它與運算符重載函數相似,都是用關鍵字operator開頭,只是被重載的是類型名?double類型經過重載后,除了原有的含義外,還獲得新的含義(將一個Complex類對象轉換為double類型數據,并指定了轉換方法)?這樣,編譯系統不僅能識別原有的double型數據,而且還會把Complex類對象作為double型數據處理?[cpp] // TypeSwitch.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; class Complex { public: Complex():real(0),imag(0){}; Complex(double r, double i):real(r),imag(i){}; Complex(double r):real(r),imag(0){}; // 定義轉換構造函數 void Print(){ cout<<"real = " << real <<" image = "<<imag<<endl; } operator double(){ // 定義類型轉換函數 return real; } private: double real; double imag; }; int main(int argc, _TCHAR* argv[]) { Complex c1(1.2, 2.3); double d; d = c1 + 1.1; // 調用類型轉換函數將c1轉換為double cout<<d<<endl; return 0; } 本例中,對于d = c1 + 1.1;先調用類型轉換函數將c1轉為double類型,然后在與1.1相加! 那么程序中的Complex類對具有雙重身份,既是Complex類對象,又可作為double類型數據?Complex類對象只有在需要時才進行轉換,要根據表達式的上下文來決定?轉換構造函數和類型轉換運算符有一個共同的功能: 當需要的時候,編譯系統會自動調用這些函數,建立一個無名的臨時對象(或臨時變量)?新聞熱點
疑難解答
圖片精選