但是從沒(méi)聽(tīng)說(shuō)過(guò)轉(zhuǎn)換構(gòu)造函數(shù),隱式轉(zhuǎn)換函數(shù)也是一樣,C++的確是夠博大精深的,再次嘆服!
其實(shí)我們已經(jīng)在C/C++中見(jiàn)到過(guò)多次標(biāo)準(zhǔn)類型數(shù)據(jù)間的轉(zhuǎn)換方式了,這種形式用于在程序中將一種指定的數(shù)據(jù)轉(zhuǎn)換成另一指定的類型,也即是強(qiáng)制轉(zhuǎn)換,比如:int a = int(1.23),其作用是將1.23轉(zhuǎn)換為整形1.然而對(duì)于用戶自定義的類類型,編譯系統(tǒng)并不知道如何進(jìn)行轉(zhuǎn)換,所以需要定義專門(mén)的函數(shù)來(lái)告訴編譯系統(tǒng)改如何轉(zhuǎn)換,這就是轉(zhuǎn)換構(gòu)造函數(shù)和類型轉(zhuǎn)換函數(shù)!
一、轉(zhuǎn)換構(gòu)造函數(shù)
轉(zhuǎn)換構(gòu)造函數(shù)(conversion constructor function) 的作用是將一個(gè)其他類型的數(shù)據(jù)轉(zhuǎn)換成一個(gè)類的對(duì)象?
當(dāng)一個(gè)構(gòu)造函數(shù)只有一個(gè)參數(shù),而且該參數(shù)又不是本類的const引用時(shí),這種構(gòu)造函數(shù)稱為轉(zhuǎn)換構(gòu)造函數(shù)。
轉(zhuǎn)換構(gòu)造函數(shù)是對(duì)構(gòu)造函數(shù)的重載。
例如:
[cpp]
Complex(double r)
{
real=r;
imag=0;
}
其作用是將double型的參數(shù)r轉(zhuǎn)換成Complex類的對(duì)象,將r作為復(fù)數(shù)的實(shí)部,虛部為0?用戶可以根據(jù)需要定義轉(zhuǎn)換構(gòu)造函數(shù),在函數(shù)體中告訴編譯系統(tǒng)怎樣去進(jìn)行轉(zhuǎn)換?
那么如何使用轉(zhuǎn)換構(gòu)造函數(shù)進(jìn)行類型轉(zhuǎn)換呢?我們看如下的例子:
[cpp]
// TypeSwitch.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//
#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){}; // 定義轉(zhuǎn)換構(gòu)造函數(shù)
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; // 調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)將1.2轉(zhuǎn)換為Complex類型
c.Print();
Complex c1(2.9, 4.2);
Complex c2 = c1 + 3.1; // 調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)將3.1轉(zhuǎn)換為Complex類型
c2.Print();
return 0;
}
不僅可以將一個(gè)標(biāo)準(zhǔn)類型數(shù)據(jù)轉(zhuǎn)換成類對(duì)象,也可以將另一個(gè)類的對(duì)象轉(zhuǎn)換成轉(zhuǎn)換構(gòu)造函數(shù)所在的類對(duì)象?如可以將一個(gè)學(xué)生類對(duì)象轉(zhuǎn)換為教師類對(duì)象,可以在Teacher類中寫(xiě)出下面的轉(zhuǎn)換構(gòu)造函數(shù):
[cpp]
Teacher(Student& s)
{
num=s.num;
strcpy(name,s.name);
sex=s.sex;
}
使用方法同上!
注意:
1.用轉(zhuǎn)換構(gòu)造函數(shù)可以將一個(gè)指定類型的數(shù)據(jù)轉(zhuǎn)換為類的對(duì)象?但是不能反過(guò)來(lái)將一個(gè)類的對(duì)象轉(zhuǎn)換為一個(gè)其他類型的數(shù)據(jù)(例如將一個(gè)Complex類對(duì)象轉(zhuǎn)換成double類型數(shù)據(jù))?
2.如果不想讓轉(zhuǎn)換構(gòu)造函數(shù)生效,也就是拒絕其它類型通過(guò)轉(zhuǎn)換構(gòu)造函數(shù)轉(zhuǎn)換為本類型,可以在轉(zhuǎn)換構(gòu)造函數(shù)前面加上explicit!例如sat答案
[cpp]
// TypeSwitch.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//
#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禁止構(gòu)造函數(shù)的轉(zhuǎn)換功能
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; // 調(diào)用類型轉(zhuǎn)換函數(shù)將c1轉(zhuǎn)換為double,編譯出錯(cuò)!
cout《d《endl;
return 0;
}
二、類型轉(zhuǎn)換函數(shù)
用轉(zhuǎn)換構(gòu)造函數(shù)可以將一個(gè)指定類型的數(shù)據(jù)轉(zhuǎn)換為類的對(duì)象?但是不能反過(guò)來(lái)將一個(gè)類的對(duì)象轉(zhuǎn)換為一個(gè)其他類型的數(shù)據(jù)(例如將一個(gè)Complex類對(duì)象轉(zhuǎn)換成double類型數(shù)據(jù))?而類型轉(zhuǎn)換函數(shù)就是專門(mén)用來(lái)解決這個(gè)問(wèn)題的!
類型轉(zhuǎn)換函數(shù)的作用是將一個(gè)類的對(duì)象轉(zhuǎn)換成另一類型的數(shù)據(jù)?
如果已聲明了一個(gè)Complex類,可以在Complex類中這樣定義類型轉(zhuǎn)換函數(shù):
[cpp]
operator double( )
{
return real;
}
類型轉(zhuǎn)換函數(shù)的一般形式為:
operator 類型名( )
{
實(shí)現(xiàn)轉(zhuǎn)換的語(yǔ)句
}
注意事項(xiàng):
1.在函數(shù)名前面不能指定函數(shù)類型,函數(shù)沒(méi)有參數(shù)?
2.其返回值的類型是由函數(shù)名中指定的類型名來(lái)確定的?
3.類型轉(zhuǎn)換函數(shù)只能作為成員函數(shù),因?yàn)檗D(zhuǎn)換的主體是本類的對(duì)象,不能作為友元函數(shù)或普通函數(shù)?
4.從函數(shù)形式可以看到,它與運(yùn)算符重載函數(shù)相似,都是用關(guān)鍵字operator開(kāi)頭,只是被重載的是類型名?double類型經(jīng)過(guò)重載后,除了原有的含義外,還獲得新的含義(將一個(gè)Complex類對(duì)象轉(zhuǎn)換為double類型數(shù)據(jù),并指定了轉(zhuǎn)換方法)?這樣,編譯系統(tǒng)不僅能識(shí)別原有的double型數(shù)據(jù),而且還會(huì)把Complex類對(duì)象作為double型數(shù)據(jù)處理托福答案
[cpp]
// TypeSwitch.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//
#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){}; // 定義轉(zhuǎn)換構(gòu)造函數(shù)
void Print(){
cout《"real = " 《 real 《" image = "《imag《endl;
}
operator double(){ // 定義類型轉(zhuǎn)換函數(shù)
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; // 調(diào)用類型轉(zhuǎn)換函數(shù)將c1轉(zhuǎn)換為double
cout《d《endl;
return 0;
}
本例中,對(duì)于d = c1 + 1.1;先調(diào)用類型轉(zhuǎn)換函數(shù)將c1轉(zhuǎn)為double類型,然后在與1.1相加!
那么程序中的Complex類對(duì)具有雙重身份,既是Complex類對(duì)象,又可作為double類型數(shù)據(jù)?Complex類對(duì)象只有在需要時(shí)才進(jìn)行轉(zhuǎn)換,要根據(jù)表達(dá)式的上下文來(lái)決定?轉(zhuǎn)換構(gòu)造函數(shù)和類型轉(zhuǎn)換運(yùn)算符有一個(gè)共同的功能: 當(dāng)需要的時(shí)候,編譯系統(tǒng)會(huì)自動(dòng)調(diào)用這些函數(shù),建立一個(gè)無(wú)名的臨時(shí)對(duì)象(或臨時(shí)變量)?