C語言是一個有結構化程式設計、具有變數作用域(variable scope)以及遞迴功能的過程式語言。以下是小編為大家搜尋整理的C++類的轉換, 希望能給大家帶來幫助!更多精彩內容請及時關注我們應屆畢業生考試網!
C++的內部資料型別遵循隱式型別轉換規則。假設某個表達市中使用了一個短整型變數,而編譯器根據上下文認為這兒需要是的長整型,則編譯器就會根據型別轉換規則自動把它轉換成長整型,這種隱式轉換出現在賦值、引數傳遞、返回值、初始化和表示式中。我們也可以為類提供相應的轉換規則。
一、轉換建構函式
當一個建構函式僅有一個引數,且該引數是不同於該類的一個數據型別,這樣的建構函式就叫轉換建構函式。轉換建構函式把別的資料型別的物件轉換為該類的一個物件。和其他建構函式一樣,如果宣告類的物件的初始化表同轉換建構函式的引數表相匹配,該函式就會被呼叫。當在需要使用該類的地方使用了別的資料型別,便宜器就會呼叫轉換建構函式進行轉換。
#include iostream.h
#include time.h
#include stdio.h
class Date
{
int mo, da, yr;
public:
Date(time_t);
void display();
};
void Date::display()
{
char year[5];
if(yr<10)
sprintf(year,0%d,yr);
else
sprintf(year,%d,yr);
cout< }
Date::Date(time_t now)
{
tm* tim=localtime(&now);
da=tim->tm_mday;
mo=tim->tm_mon+1;
yr=tim->tm_year;
if(yr>=100) yr-=100;
}
int main()
{
time_t now=time(0);
Date dt(now);
lay();
return 0;
}
本程式先呼叫time()函式來獲取當前時間,並把它賦給time_t物件;然後程式通過呼叫Date類的.轉換建構函式來建立一個Date物件,該物件由time_t物件轉換而來。time_t物件先傳遞給localtime()函式,然後返回一個指向tm結構(time.h檔案中宣告)的指標,然後建構函式把結構中的日月年的數值拷貝給Date物件的資料成員,這就完成了從time_t物件到Date物件的轉換。
二、成員轉換函式
成員轉換函式把該類的物件轉換為其他資料型別的物件。在成員轉換函式的宣告中要用到關鍵字operator。這樣宣告一個成員轉換函式:
operator aaa();
在這個例子中,aaa就是要轉換成的資料型別的說明符。這裡的型別說明符可以是任何合法的C++型別,包括其他的類。如下來定義成員轉換函式;
Classname::operator aaa()
類名識別符號是聲明瞭該函式的類的型別說明符。上面定義的Date類並不能把該類的物件轉換回time_t型變數,但可以把它轉換成一個長整型值,計算從2000年1月1日到現在的天數。
#include iostream.h
class Date
{
int mo,da,yr;
public:
Date(int m,int d,int y) {mo=m; da=d; yr=y;}
operator int(); //宣告
};
Date::operator int() //定義
{
static int dys[]={31,28,31,30,31,30,31,31,30,31,30,31};
int days=yr-2000;
days*=365;
days+=(yr-2000)/4;
for(int i=0;i days+=dys[i];
days+=da;
return days;
}
int main()
{
Date now(12,24,2003);
int since=now;
cout< return 0;
}
三、類的轉換
上面兩個例子都是C++類物件和內部資料物件之間的相互轉換。也可以定義轉換函式來實現兩個類物件之間的相互轉換。
#include iostream.h
class CustomDate
{
public:
int da, yr;
CustomDate(int d=0,int y=0) {da=d; yr=y;}
void display()
{
cout< }
};
class Date
{
int mo, da, yr;
public:
Date(int m=0,int d=0,int y=0) {mo=m; da=d; yr=y;}
Date(const CustomDate&); //轉換建構函式
operator CustomDate(); //成員轉換函式
void display()
{
cout< }
};
static int dys[] = {31,28,31,30,31,30,31,31,30,31,30,31};
Date::Date(const CustomDate& jd)
{
yr=;
da=;
for(mo=0;mo<11;mo++)
if(da>dys[mo]) da-=dys[mo];
else break;
mo++;
}
Date::operator CustomDate()
{
CustomDate cd(0,yr);
for(int i=0;i +=da;
return cd;
}
int main()
{
Date dt(12,24,3);
CustomDate cd;
cd = dt; //呼叫成員轉換函式
lay();
dt = cd; //呼叫轉換建構函式
lay();
return 0;
}
這個例子中有兩個類CustomDate和Date,CustomDate型日期包含年份和天數。
這個例子沒有考慮閏年情況。但是在實際構造一個類時,應該考慮到所有問題的可能性。
在Date裡中具有兩種轉換函式,這樣,當需要從Date型變為CustomDate型十,可以呼叫成員轉換函式;反之可以呼叫轉換建構函式。
不能既在Date類中定義成員轉換函式,又在CustomDate類裡定義轉換建構函式。那樣編譯器在進行轉換時就不知道該呼叫哪一個函式,從而出錯.
四、轉換函式的呼叫
C++裡呼叫轉換函式有三種形式:第一種是隱式轉換,例如編譯器需要一個Date物件,而程式提供的是CustomDate物件,編譯器會自動呼叫合適的轉換函式。另外兩種都是需要在程式程式碼中明確給出的顯式轉換。C++強制型別轉換是一種,還有一種是顯式呼叫轉換建構函式和成員轉換函式。下面的程式給出了三中轉換形式:
#include iostream.h
class CustomDate
{
public:
int da, yr;
CustomDate(int d=0,int y=0) {da=d; yr=y;}
void display()
{
cout< }
};
class Date
{
int mo, da, yr;
public:
Date(int m,int d,int y)
{
mo=m; da=d; yr=y;
}
operator CustomDate();
};
Date::operator CustomDate()
{
static int dys[]={31,28,31,30,31,30,31,31,30,31,30,31};
CustomDate cd(0,yr);
for(int i=0;i +=da;
return cd;
}
int main()
{
Date dt(11,17,89);
CustomDate cd;
cd = dt;
lay();
cd = (CustomDate) dt;
lay();
cd = CustomDate(dt);
lay();
return 0;
}
五、轉換髮生的情形
上面的幾個例子都是通過不能型別物件之間的相互賦值來呼叫轉換函式,還有幾種呼叫的可能:
引數傳遞
初始化
返回值
表示式語句
這些情況下,都有可能呼叫轉換函式。
下面的程式不難理解,就不分析了。
#include iostream.h
class CustomDate
{
public:
int da, yr;
CustomDate() {}
CustomDate(int d,int y) { da=d; yr=y;}
void display()
{
cout< }
};
class Date
{
int mo, da, yr;
public:
Date(int m,int d,int y) { mo=m; da=d; yr=y; }
operator CustomDate();
};
Date::operator CustomDate()
{
static int dys[]={31,28,31,30,31,30,31,31,30,31,30,31};
CustomDate cd(0,yr);
for (int i=0;i +=da;
return cd;
}
class Tester
{
CustomDate cd;
public:
explicit Tester(CustomDate c) { cd=c; }
void display() { lay(); }
};
void dispdate(CustomDate cd)
{
lay();
}
CustomDate rtndate()
{
Date dt(9,11,1);
return dt;
}
int main()
{
Date dt(12,24,3);
CustomDate cd;
cd = dt;
lay();
dispdate(dt);
Tester ts(dt);
lay();
cd = rtndate();
lay();
return 0;
}
六、顯式建構函式
注意上面Tester類的建構函式前面有一個explicit修飾符。如果不加上這個關鍵字,那麼在需要把CustomDate物件轉換成Tester物件時,編譯器會把該函式當作轉換建構函式來呼叫。但是有時候,並不想把這種只有一個引數的建構函式用於轉換目的,而僅僅希望用它來顯式地初始化物件,此時,就需要在建構函式前加explicit。如果在聲明瞭Tester物件以後使用了下面的語句將導致一個錯誤:
ts=jd; //error
這個錯誤說明,雖然Tester類中有一個以Date型變數為引數的建構函式,編譯器卻不會把它看作是從Date到Tester的轉換建構函式,因為它的宣告中包含了explicit修飾符。
七、表示式內部的轉換
在表示式內部,如果發現某個型別和需要的不一致,就會發生錯誤。數字型別的轉換是很簡單,這裡就不舉例了。下面的程式是把Date物件轉換成長整型值。
#include iostream.h
class Date
{
int mo, da, yr;
public:
Date(int m,int d,int y)
{
mo=m; da=d; yr=y;
}
operator long();
};
Date::operator long()
{
static int dys[]={31,28,31,30,31,30,31,31,30,31,30,31};
long days=yr;
days*=365;
days+=(yr-1900)/4; //從1900年1月1日開始計算
for(int i=0;i days+=da;
return days;
}
int main()
{
Date today(12,24,2003);
const long ott=123;
long sum=ott+today;
cout< return 0;
}
在表示式中,當需要轉換的物件可以轉換成某個數字型別,或者表示式呼叫了作用於某個類的過載運算子時,就會發生隱式轉換。運算子過載以後再學習。