C 入門 三 類的轉換

2021-06-08 04:39:19 字數 3847 閱讀 5825

c++的內部資料型別遵循隱式型別轉換規則。假設某個表達市中使用了乙個短整型變數,而編譯器根據上下文認為這兒需要是的長整型,則編譯器就會根據型別轉換規則自動把它轉換成長整型,這種隱式轉換出現在賦值、引數傳遞、返回值、初始化和表示式中。我們也可以為類提供相應的轉換規則。

對乙個類建立隱式轉換規則需要構造乙個轉換函式,該函式作為類的成員,可以把該類的物件和其他資料型別的物件進行相互轉換。宣告了轉換函式,就告訴了編譯器,當根據句法判定需要型別轉換時,就呼叫函式。

有兩種轉換函式。一種是轉換建構函式;另一種是成員轉換函式。需要採用哪種轉換函式取決於轉換的方向。

一、轉換建構函式

當乙個建構函式僅有乙個引數,且該引數是不同於該類的乙個資料型別,這樣的建構函式就叫轉換建構函式。轉換建構函式把別的資料型別的物件轉換為該類的乙個物件。和其他建構函式一樣,如果宣告類的物件的初始化表同轉換建構函式的參數列相匹配,該函式就會被呼叫。當在需要使用該類的地方使用了別的資料型別,便宜器就會呼叫轉換建構函式進行轉換。

#include iostream.h

#include time.h

#include stdio.h

class date

;void date::display()

date::date(time_t now)

int main()

本程式先呼叫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型變數,但可以把它轉換成乙個長整型值,計算從2023年1月1日到現在的天數。

#include iostream.h

class date

operator int(); //宣告

};date::operator int() //定義

;int days=yr-2000;

days*=365;

days+=(yr-2000)/4;

for(int i=0;i days+=dys[i];

days+=da; 

return days;

}int main()

三、類的轉換

上面兩個例子都是c++類物件和內部資料物件之間的相互轉換。也可以定義轉換函式來實現兩個類物件之間的相互轉換。

#include iostream.h

class customdate

void display()

};class date

date(const customdate&); //轉換建構函式

operator customdate(); //成員轉換函式

void display()

};static int dys = ;

date::date(const customdate& jd)

date::operator customdate()

int main()

這個例子中有兩個類customdate和date,customdate型日期包含年份和天數。

這個例子沒有考慮閏年情況。但是在實際構造乙個類時,應該考慮到所有問題的可能性。

在date裡中具有兩種轉換函式,這樣,當需要從date型變為customdate型十,可以呼叫成員轉換函式;反之可以呼叫轉換建構函式。

不能既在date類中定義成員轉換函式,又在customdate類裡定義轉換建構函式。那樣編譯器在進行轉換時就不知道該呼叫哪乙個函式,從而出錯。

四、轉換函式的呼叫

c++裡呼叫轉換函式有三種形式:第一種是隱式轉換,例如編譯器需要乙個date物件,而程式提供的是customdate物件,編譯器會自動呼叫合適的轉換函式。另外兩種都是需要在程式**中明確給出的顯式轉換。c++強制型別轉換是一種,還有一種是顯式呼叫轉換建構函式和成員轉換函式。下面的程式給出了三中轉換形式:

#include iostream.h

class customdate

void display()

};class date

operator customdate();

};date::operator customdate()

;customdate cd(0,yr);

for(int i=0;i cd.da+=da;

return cd;

}int main()

五、轉換發生的情形

上面的幾個例子都是通過不能型別物件之間的相互賦值來呼叫轉換函式,還有幾種呼叫的可能:

引數傳遞

初始化返回值

表示式語句

這些情況下,都有可能呼叫轉換函式。

下面的程式不難理解,就不分析了。

#include iostream.h

class customdate

customdate(int d,int y)

void display()

};class date

operator customdate(); 

}; date::operator customdate()

;customdate cd(0,yr);

for (int i=0;i cd.da+=da;

return cd;

}class tester

void display()

};void dispdate(customdate cd)

customdate r***ate()

int main()

六、顯式建構函式

注意上面tester類的建構函式前面有乙個explicit修飾符。如果不加上這個關鍵字,那麼在需要把customdate物件轉換成tester物件時,編譯器會把該函式當作轉換建構函式來呼叫。但是有時候,並不想把這種只有乙個引數的建構函式用於轉換目的,而僅僅希望用它來顯式地初始化物件,此時,就需要在建構函式前加explicit。如果在宣告了tester物件以後使用了下面的語句將導致乙個錯誤:

ts=jd; //error

這個錯誤說明,雖然tester類中有乙個以date型變數為引數的建構函式,編譯器卻不會把它看作是從date到tester的轉換建構函式,因為它的宣告中包含了explicit修飾符。

七、表示式內部的轉換

在表示式內部,如果發現某個型別和需要的不一致,就會發生錯誤。數字型別的轉換是很簡單,這裡就不舉例了。下面的程式是把date物件轉換成長整型值。

#include iostream.h

class date

operator long();

};date::operator long()

;long days=yr;

days*=365;

days+=(yr-1900)/4; //從2023年1月1日開始計算

for(int i=0;i days+=da;

return days;

}int main()

在表示式中,當需要轉換的物件可以轉換成某個數字型別,或者表示式呼叫了作用於某個類的過載運算子時,就會發生隱式轉換。運算子過載以後再學習。

三 類的複製(C )

內容參考於 21天學通c 第八版 不去糾結c 的原理和細節,從c的角度去學習c 再通過c 專案去加深理解 1.示例1 淺複製及其存在的問題 include include using namespace std class mystring mystring destructor intgetlen...

三類MySQL MySQL常用的三類函式

經常編寫程式或者使用資料庫的同學一定體會到函式的重要性,豐富的函式往往能使使用者的工作事半功倍。函式能幫助使用者做很多事情,比如說字串的處理 數值的運算 日期的運算等,在這方面mysql提供了多種內建函式幫助開發人員編寫簡單快捷的sql語句,其中常用的函式有字串函式 日期函式和數值函式。1 字串函式...

C 複習三 類的繼承

繼承中的一些問題 多繼承虛基類 繼承總結 繼承 自動從另一種事物獲取部分或全部的屬性和能力 繼承提高了 的可重用性 class 子類名 public protected private 父類名子類繼承父類的所有內容,包括私有屬性 只是我們看不到 public protected private pu...