今天是第一次聽到C++還有個轉換構造函數,以前常常見到默認構造函數、拷貝構造函數、析構函數,可是從沒據說過轉換構造函數,隱式轉換函數也是同樣,C++的確是夠博大精深的,再次歎服!ios
其實咱們已經在C/C++中見到過屢次標準類型數據間的轉換方式了,這種形式用於在程序中將一種指定的數據轉換成另外一指定的類型,也便是強制轉換,好比:int a = int(1.23),其做用是將1.23轉換爲整形1。然而對於用戶自定義的類類型,編譯
系統並不知道如何進行轉換,因此須要定義專門的函數來告訴編譯系統改如何轉換,這就是轉換構造函數和類型轉換函數!
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;
}
2、類型轉換函數
用轉換構造函數能夠將一個指定類型的數據轉換爲類的對象。可是不能反過來將一個類的對象轉換爲一個其餘類型的數據(例如將一個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類對象只有在須要時才進行轉換,要根據表達式的上下文來決定。轉換構造函數和類型轉換運算符有一個共同的功能: 當須要的時候,編譯系統會自動調用這些函數,創建一個無名的臨時對象(或臨時變量)。