




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、面向?qū)ο蟪绦蛟O計面向?qū)ο蟪绦蛟O計十、其他十、其他n嵌套類嵌套類n類型轉(zhuǎn)換類型轉(zhuǎn)換n在一個類的內(nèi)部定義另一個類,稱之為嵌套類在一個類的內(nèi)部定義另一個類,稱之為嵌套類(nested class)(nested class),或嵌套類型,或嵌套類型(nested type)(nested type)。n之所以引入這樣一個嵌套類,往往是因為外圍類之所以引入這樣一個嵌套類,往往是因為外圍類需要使用嵌套類對象作為底層實現(xiàn),并且該嵌套需要使用嵌套類對象作為底層實現(xiàn),并且該嵌套類只用于外圍類的實現(xiàn)。通過嵌套類機制,可以類只用于外圍類的實現(xiàn)。通過嵌套類機制,可以對用戶隱藏該嵌套類的實現(xiàn),減少全局的標識符對用戶隱
2、藏該嵌套類的實現(xiàn),減少全局的標識符,限制用戶使用該類建立對象。,限制用戶使用該類建立對象。第10章其他2022-6-284n嵌套類是其外圍類的一個成員,像其他任何成員嵌套類是其外圍類的一個成員,像其他任何成員一樣,外圍類決定對這個類型的訪問,在外圍類一樣,外圍類決定對這個類型的訪問,在外圍類的的publicpublic部分定義的嵌套類是可在任何地方使用部分定義的嵌套類是可在任何地方使用的類型,在的類型,在protectedprotected部分的嵌套類是只能由外部分的嵌套類是只能由外圍類、友元或派生類訪問的類型,在圍類、友元或派生類訪問的類型,在privateprivate部部分的嵌套類是只能
3、由外圍類、友元訪問的類型。分的嵌套類是只能由外圍類、友元訪問的類型。n嵌套類的名字在其外圍類的作用域中是可見的,嵌套類的名字在其外圍類的作用域中是可見的,但是在其他類域或名字空間中是不可見的,這意但是在其他類域或名字空間中是不可見的,這意味著嵌套類的名字不會與另一作用域中聲明的相味著嵌套類的名字不會與另一作用域中聲明的相同名字沖突。同名字沖突。n雖然嵌套類在外圍類內(nèi)部定義,但它是一個獨立雖然嵌套類在外圍類內(nèi)部定義,但它是一個獨立的類,基本上與外圍類不相關。它的成員不屬于的類,基本上與外圍類不相關。它的成員不屬于外圍類,外圍類的成員也不屬于該嵌套類。嵌套外圍類,外圍類的成員也不屬于該嵌套類。嵌套
4、類的出現(xiàn)只是告訴外圍類有一個這樣的類型成員類的出現(xiàn)只是告訴外圍類有一個這樣的類型成員供外圍類使用。供外圍類使用。n外圍類對嵌套類成員的訪問沒有任何特權(quán),嵌套外圍類對嵌套類成員的訪問沒有任何特權(quán),嵌套類對外圍類成員的訪問也同樣如此,它們都遵循類對外圍類成員的訪問也同樣如此,它們都遵循普通類的訪問權(quán)限控制規(guī)則。普通類的訪問權(quán)限控制規(guī)則。n嵌套類可以直接引用外圍類的靜態(tài)成員、類型名嵌套類可以直接引用外圍類的靜態(tài)成員、類型名和枚舉成員,即使這些是和枚舉成員,即使這些是privateprivate的。的。第10章其他2022-6-286n嵌套類一般定義在外圍類的類體內(nèi)。嵌套類的成嵌套類一般定義在外圍類的
5、類體內(nèi)。嵌套類的成員函數(shù)可以其類體內(nèi)定義,也可以在其類體外定員函數(shù)可以其類體內(nèi)定義,也可以在其類體外定義,但必須在外圍類的同一作用域中,且要用外義,但必須在外圍類的同一作用域中,且要用外圍類進行限定。圍類進行限定。n嵌套類也可在外圍類外或另一個頭文件中定義,嵌套類也可在外圍類外或另一個頭文件中定義,并在外圍類中前向聲明這個嵌套類即可。當然,并在外圍類中前向聲明這個嵌套類即可。當然,在外圍類外面定義這個嵌套類時,應該使用外圍在外圍類外面定義這個嵌套類時,應該使用外圍類進行限定。如果在另一個頭文件中定義,使用類進行限定。如果在另一個頭文件中定義,使用時,只需要在外圍類的實現(xiàn)文件中包含這個頭文時,只
6、需要在外圍類的實現(xiàn)文件中包含這個頭文件即可。件即可。第10章其他2022-6-287n比較好的設計是把嵌套類定義為外圍類的私有成比較好的設計是把嵌套類定義為外圍類的私有成員,避免該嵌套類可以在整個程序中員,避免該嵌套類可以在整個程序中( (在外圍類在外圍類的友元和成員定義之外的友元和成員定義之外) )用作類型。有了這個方用作類型。有了這個方法,我們把嵌套類的所有成員都聲明為公有的也法,我們把嵌套類的所有成員都聲明為公有的也不再有任何壞處,因為只有外圍類的友元和成員不再有任何壞處,因為只有外圍類的友元和成員 可以訪問嵌套類的成員。我們也不需要在嵌套類可以訪問嵌套類的成員。我們也不需要在嵌套類中對
7、外圍類進行友元聲明了。中對外圍類進行友元聲明了。第10章其他2022-6-288/示例嵌套類定義示例嵌套類定義class List class List public:public:/ ./ .private:private:class ListItemclass ListItem / / 它的成員都是公有的它的成員都是公有的public:public:ListItem( int valListItem( int val = 0 ); = 0 );ListItemListItem * *next;next;intint value; value;ListItemListItem * *list
8、;list;ListItem ListItem * *at_endat_end; ;第10章其他2022-6-289/ / 用外圍類名限定修飾嵌套類名用外圍類名限定修飾嵌套類名List:ListItem:List:ListItem:ListItem( int valListItem( int val ) ) value = valvalue = val; ;next = 0;next = 0; n 當我們沒有在嵌套類體內(nèi)以當我們沒有在嵌套類體內(nèi)以inline inline 形式定義嵌套類的形式定義嵌套類的成員函數(shù)時,我們就必須在最外圍的類之外定義這些成成員函數(shù)時,我們就必須在最外圍的類之外定義
9、這些成員函數(shù),并員函數(shù),并用外圍類名限定修飾嵌套類名用外圍類名限定修飾嵌套類名。第10章其他2022-6-2810n在嵌套類的定義被看到之前,我們只能聲明嵌套在嵌套類的定義被看到之前,我們只能聲明嵌套類的指針和引用。類的指針和引用。class List class List public:public:/ ./ .private:private:/ / 這個聲明是必需的這個聲明是必需的class ListItemclass ListItem; ;ListItemListItem * *list;list;ListItem at_endListItem at_end; /; /錯誤錯誤: : 未
10、定義嵌套類未定義嵌套類ListItemListItem;第10章其他2022-6-2811n嵌套類不能直接訪問其外圍類的非靜態(tài)成員,即嵌套類不能直接訪問其外圍類的非靜態(tài)成員,即使這些成員是公有的,任何對外圍類的非靜態(tài)成使這些成員是公有的,任何對外圍類的非靜態(tài)成員的訪問都要求通過外圍類的指針,引用或?qū)ο髥T的訪問都要求通過外圍類的指針,引用或?qū)ο髞硗瓿?。例如:來完成。例如:?0章其他2022-6-2812class List class List public:public:int init( intint init( int ); );private:private:class ListIte
11、mclass ListItem public:public:ListItem( int valListItem( int val = 0 ); = 0 );void mf( const List & );void mf( const List & );intint value; value;int membint memb; ;List:ListItem:ListItem( int valList:ListItem:ListItem( int val ) ) / List:init/ List:init() () 是類是類 List List 的非靜態(tài)成員的非靜態(tài)成員value
12、 = init( valvalue = init( val ); / ); / 錯誤錯誤: : 非法使用非法使用 initinit/ / 必須通過必須通過 List List 類型的對象或指針來使用類型的對象或指針來使用 第10章其他2022-6-2813n使用類的非靜態(tài)成員時,編譯器必須能夠識別出使用類的非靜態(tài)成員時,編譯器必須能夠識別出非靜態(tài)成員屬于哪個對象。在非靜態(tài)成員屬于哪個對象。在ListItemListItem的構(gòu)造函的構(gòu)造函數(shù)中的數(shù)中的thisthis指針的類型是指針的類型是ListItemListItem* * ,而要訪問,而要訪問成員成員init()init()所需的是所需的
13、是ListList類型的對象或類型的對象或ListList* *類類型的指針。型的指針。n成員函數(shù)成員函數(shù)mf()mf()通過引用參數(shù)引用通過引用參數(shù)引用init()init(),從這里,從這里我們能夠知道成員我們能夠知道成員init()init()是針對函數(shù)實參指定的是針對函數(shù)實參指定的對象而被調(diào)用的。對象而被調(diào)用的。void List:ListItem:mfvoid List:ListItem:mf( ( const List &ilconst List &il ) ) memb = il.initmemb = il.init();(); / ok: / ok: 通過引用調(diào)
14、用通過引用調(diào)用init()init() 第10章其他2022-6-2814n嵌套類可以直接訪問外圍類的靜態(tài)成員,類型名嵌套類可以直接訪問外圍類的靜態(tài)成員,類型名,枚舉值。類型名是一個,枚舉值。類型名是一個typedeftypedef名字,枚舉類名字,枚舉類型名,或是一個類名。例如:型名,或是一個類名。例如:n在在ListItemListItem的域之外,以及在外圍類的域之外,以及在外圍類List List 域之域之外引用外圍類的靜態(tài)成員類型名和枚舉名都要求外引用外圍類的靜態(tài)成員類型名和枚舉名都要求域解析操作符。域解析操作符。第10章其他2022-6-2815class List class L
15、ist public:public:typedef int (typedef int (* *pFuncpFunc)();)();enum ListStatusenum ListStatus Good, Empty, Corrupted ; Good, Empty, Corrupted ;/ ./ .private:private:class ListItemclass ListItem public:public:void check_statusvoid check_status();();ListStatusListStatus status; / ok status; / okpFun
16、cpFunc action; / ok action; / ok/ ./ .;/ ./ .;第10章其他2022-6-2816npFuncpFunc,ListStatusListStatus和和ListItemListItem都是外圍類都是外圍類List List 的作用域內(nèi)部的嵌套類型名,這三個名字以及的作用域內(nèi)部的嵌套類型名,這三個名字以及ListStatusListStatus的枚舉值都可以被用在的枚舉值都可以被用在ListItemListItem的域的域中,這些成員可以不加限定修飾地被引用。中,這些成員可以不加限定修飾地被引用。void List:ListItem:check_stat
17、usvoid List:ListItem:check_status()() ListStatusListStatus s = status; s = status;switch ( s ) switch ( s ) case case EmptyEmpty: .: .case Corrupted: .case Corrupted: .case Good: .case Good: . 第10章其他2022-6-2817n被用在嵌套類的定義中的名字(除了被用在嵌套類的定義中的名字(除了inline inline 成成員函數(shù)定義中的名字和缺省實參的名字之外)其員函數(shù)定義中的名字和缺省實參的名字之外)
18、其解析過程如下:解析過程如下:1.1.考慮出現(xiàn)在名字使用點之前的嵌套類的成員聲考慮出現(xiàn)在名字使用點之前的嵌套類的成員聲明。明。2.2.如果第如果第1 1步?jīng)]有成功則考慮出現(xiàn)在名字使用點步?jīng)]有成功則考慮出現(xiàn)在名字使用點之前的外圍類的成員聲明。之前的外圍類的成員聲明。3.3.如果第如果第2 2步?jīng)]有成功則考慮出現(xiàn)在嵌套類定義步?jīng)]有成功則考慮出現(xiàn)在嵌套類定義之前的名字空間域中的聲明。之前的名字空間域中的聲明。第10章其他2022-6-2818enum ListStatusenum ListStatus Good, Empty, Corrupted ; Good, Empty, Corrupted ;
19、class List class List public:public:/ ./ .private:private:class ListItemclass ListItem public:public:/ / 查找查找: :/ 1) / 1) 在在 List:ListItemList:ListItem 中中/ 2) / 2) 在在 List List 中中/ 3) / 3) 在全局域中在全局域中ListStatusListStatus status; / status; / 引用全局枚舉引用全局枚舉/ ./ .;/ ./ .;第10章其他2022-6-2819n編譯器首先在類編譯器首先在類Li
20、stItemListItem的域中查找的域中查找ListStatusListStatus 的聲明,因為沒有找到成員聲明,所以編譯器接的聲明,因為沒有找到成員聲明,所以編譯器接著在類著在類ListList的域中查找的域中查找ListStatusListStatus的聲明,因為的聲明,因為在在ListList類中也沒有找到聲明,于是編譯器在全局類中也沒有找到聲明,于是編譯器在全局域中查找域中查找ListStatusListStatus的聲明。在這三個域中只有的聲明。在這三個域中只有位于位于ListStatusListStatus使用點之前的聲明才會被編譯器使用點之前的聲明才會被編譯器考慮,編譯器找
21、到了全局枚舉考慮,編譯器找到了全局枚舉ListStatusListStatus的聲明的聲明,它是被用在,它是被用在statusstatus聲明中的類型。聲明中的類型。n如果在全局域中,在外圍域如果在全局域中,在外圍域ListList之外定義嵌套類之外定義嵌套類ListItemListItem,則,則ListList類的所有成員都已經(jīng)被聲明完類的所有成員都已經(jīng)被聲明完畢,因而編譯器將考慮其所有聲明,例如:畢,因而編譯器將考慮其所有聲明,例如:第10章其他2022-6-2820class List class List private:private:class ListItemclass Lis
22、tItem; ;/ ./ .public:public:enum ListStatusenum ListStatus Good, Empty, Corrupted ; Good, Empty, Corrupted ;/ ./ .;class List:ListItemclass List:ListItem public:public:/ / 查找查找: :/ 1) / 1) 在在 List:ListItemList:ListItem 中中/ 2) / 2) 在在 List List 中中/ 3) / 3) 在全局域中在全局域中ListStatus status; / List:ListStat
23、usListStatus status; / List:ListStatus/ ./ .;第10章其他2022-6-2821nListItemListItem的名字解析過程:首先在類的名字解析過程:首先在類ListItemListItem的的域中開始查找,因為沒有找到成員聲明,所以編域中開始查找,因為沒有找到成員聲明,所以編譯器在類譯器在類ListList的域內(nèi)查找的域內(nèi)查找ListStatusListStatus的聲明,因的聲明,因為類為類ListList的完整定義都已經(jīng)能夠看得到,所以這的完整定義都已經(jīng)能夠看得到,所以這一步查找考慮一步查找考慮ListList的所有成員,于是找到的所有成員
24、,于是找到ListList中中嵌套的嵌套的enumListStatusenumListStatus,盡管它是在,盡管它是在ListItemListItem之之后被聲明的,后被聲明的,statusstatus是是ListList的的ListStatusListStatus類型的類型的一個枚舉對象。如果一個枚舉對象。如果ListList沒有名為沒有名為ListStatusListStatus的的成員,則名字查找過程會在全局域中在嵌套類成員,則名字查找過程會在全局域中在嵌套類ListItemListItem定義之前查找聲明。定義之前查找聲明。第10章其他2022-6-2822n被用在被用在嵌套類的成
25、員函數(shù)嵌套類的成員函數(shù)定義中的名字,其解析定義中的名字,其解析過程如下:過程如下:1.1.首先考慮在成員函數(shù)局部域中的聲明。首先考慮在成員函數(shù)局部域中的聲明。2.2.如果第如果第1 1步?jīng)]有成功,則考慮所有嵌套類成員步?jīng)]有成功,則考慮所有嵌套類成員的聲明。的聲明。3.3.如果第如果第2 2步?jīng)]有成功,則考慮所有外圍類成員步?jīng)]有成功,則考慮所有外圍類成員的聲明。的聲明。4.4.如果第如果第3 3步?jīng)]有成功,則考慮在成員函數(shù)定義步?jīng)]有成功,則考慮在成員函數(shù)定義之前的名字空間域中出現(xiàn)的聲明。之前的名字空間域中出現(xiàn)的聲明。第10章其他2022-6-2823class List class List p
26、ublic:public:enum ListStatusenum ListStatus Good, Empty, Corrupted ; Good, Empty, Corrupted ;/ ./ .private:private:class ListItemclass ListItem public:public:void check_statusvoid check_status();();ListStatusListStatus status; / ok status; / ok/ ./ .;ListItemListItem * *listlist; ;/ ./ .;intint list
27、list = 0; = 0;void List:ListItem:check_statusvoid List:ListItem:check_status()() intint value = value = listlist; / ; / 哪個哪個 list?list? 第10章其他2022-6-2824n很有可能程序員想讓很有可能程序員想讓check_statuscheck_status()()中的中的ListList引引用全局對象:用全局對象:nvaluevalue和全局對象和全局對象listlist的類型都是的類型都是intint,List:listList:list 成員是指針類型,在
28、沒有顯式轉(zhuǎn)換的情況它不能被成員是指針類型,在沒有顯式轉(zhuǎn)換的情況它不能被賦給賦給valuevaluen不允許不允許ListItemListItem訪問其外圍類的私有數(shù)據(jù)成員訪問其外圍類的私有數(shù)據(jù)成員listlistnlistlist是一個非靜態(tài)數(shù)據(jù)成員,在是一個非靜態(tài)數(shù)據(jù)成員,在ListItemListItem的成員函的成員函數(shù)中必須通過對象指針或引用來訪問它數(shù)中必須通過對象指針或引用來訪問它n盡管有這些原因,在成員盡管有這些原因,在成員check_statuscheck_status()()中用到中用到的名字的名字listlist仍被解析為類仍被解析為類ListList的數(shù)據(jù)成員的數(shù)據(jù)成員li
29、stlist,外圍類外圍類ListList的成員的成員listlist隱藏了全局域中的對象,隱藏了全局域中的對象,于是產(chǎn)生一個錯誤消息,因為在于是產(chǎn)生一個錯誤消息,因為在check_statuscheck_status()()中使用指針中使用指針listlist是無效的。是無效的。第10章其他2022-6-2825n只有在名字解析成功之后,編譯器才會檢查訪問只有在名字解析成功之后,編譯器才會檢查訪問許可和類型兼容性。如果名字的用法本身就是錯許可和類型兼容性。如果名字的用法本身就是錯誤的,則名字解析過程將不會再去查找更適合于誤的,則名字解析過程將不會再去查找更適合于該名字用法的聲明,而是產(chǎn)生一個
30、錯誤消息。該名字用法的聲明,而是產(chǎn)生一個錯誤消息。 n為訪問全局對象為訪問全局對象listlist,需,需使用全局域操作符使用全局域操作符:void void List:ListItemList:ListItem: : check_statuscheck_status() () value = value = :list:list; / ok; / ok n如果成員函數(shù)如果成員函數(shù)check_statuscheck_status()()被定義成位于被定義成位于ListItemListItem類體中的內(nèi)聯(lián)函數(shù),則上面修改會使編類體中的內(nèi)聯(lián)函數(shù),則上面修改會使編譯器產(chǎn)生一個錯誤消息,報告全局域中的
31、譯器產(chǎn)生一個錯誤消息,報告全局域中的listlist沒沒有被聲明,因為編譯器只考慮在有被聲明,因為編譯器只考慮在check_statuscheck_status()()定義之前可見的全局聲明。定義之前可見的全局聲明。第10章其他2022-6-2826n類型轉(zhuǎn)換就是將一種類型的值映射為另一種類型類型轉(zhuǎn)換就是將一種類型的值映射為另一種類型的值。主要包含隱式類型轉(zhuǎn)換的值。主要包含隱式類型轉(zhuǎn)換(implicit type(implicit typeconversion)conversion)和顯式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換(explicit type (explicit type conversion)c
32、onversion)兩種。兩種。n隱式隱式- -自動自動n顯式顯式- -強制強制第10章其他2022-6-2827n C+C+定義了一組內(nèi)置類型對象之間的標準轉(zhuǎn)換,在必要定義了一組內(nèi)置類型對象之間的標準轉(zhuǎn)換,在必要時它們被編譯器隱式地應用到對象上,隱式類型轉(zhuǎn)換發(fā)時它們被編譯器隱式地應用到對象上,隱式類型轉(zhuǎn)換發(fā)生在下列這些典型的情況下:生在下列這些典型的情況下:1.1.在混合類型的算術表達式中。在這種情況下,在混合類型的算術表達式中。在這種情況下,最寬的數(shù)最寬的數(shù)據(jù)類型成為目標轉(zhuǎn)換類型。據(jù)類型成為目標轉(zhuǎn)換類型。這也被稱為算術轉(zhuǎn)換這也被稱為算術轉(zhuǎn)換(arithmetic conversion)(a
33、rithmetic conversion)。例如:。例如:3.14159+33.14159+32.2.用一種類型的表達式賦值給另一種類型的對象。在這種用一種類型的表達式賦值給另一種類型的對象。在這種情況下,目標轉(zhuǎn)換類型是被賦值對象的類型。例如:情況下,目標轉(zhuǎn)換類型是被賦值對象的類型。例如:int int * *pi = 0; int ivalpi = 0; int ival = 3.14159; = 3.14159;第10章其他2022-6-28283.3.把一個表達式傳遞給一個函數(shù)調(diào)用把一個表達式傳遞給一個函數(shù)調(diào)用,表達式的類型與形表達式的類型與形式參數(shù)的類型不相同。在這種情況下,目標轉(zhuǎn)換類
34、型是式參數(shù)的類型不相同。在這種情況下,目標轉(zhuǎn)換類型是形式參數(shù)的類型。形式參數(shù)的類型。例如:例如:intint a=2; sqrt(2) a=2; sqrt(2) 2-2.02-2.04.4.從一個函數(shù)返回一個表達式,表達式的類型與返回類型從一個函數(shù)返回一個表達式,表達式的類型與返回類型不相同。在這種情況下,目標轉(zhuǎn)換類型是函數(shù)的返回類不相同。在這種情況下,目標轉(zhuǎn)換類型是函數(shù)的返回類型。例如:型。例如:double difference( double difference( intint ival1, ival1, intint ival2 ) ival2 ) / / 返回值被提升為返回值被提升
35、為doubledouble 類型類型return ival1 - ival2;return ival1 - ival2; 第10章其他2022-6-2829n 顯式顯式類型轉(zhuǎn)換也被稱為強制類型轉(zhuǎn)換類型轉(zhuǎn)換也被稱為強制類型轉(zhuǎn)換(cast(cast) ),包括下列包括下列強制類型轉(zhuǎn)換操作符強制類型轉(zhuǎn)換操作符:static_caststatic_cast,dynamic_castdynamic_cast,const_castconst_cast,reinterpret_castreinterpret_cast,()()等。等。第10章其他2022-6-2830n 顯式類型轉(zhuǎn)換發(fā)生在下列這些典型的情況
36、下:顯式類型轉(zhuǎn)換發(fā)生在下列這些典型的情況下:1.1.把把voidvoid* *型的指針賦值給任意顯式類型時,型的指針賦值給任意顯式類型時,C+C+要求顯式要求顯式強制轉(zhuǎn)換。例如:強制轉(zhuǎn)換。例如:intint * *pi = 0;pi = 0;void void * * pv pv = pi; = pi;char char * * pc = pc = static_caststatic_cast char ( pv( pv ); );2.2.希望改變通常的標準轉(zhuǎn)換。例如:希望改變通常的標準轉(zhuǎn)換。例如:double dval; int ivaldouble dval; int ival; ; iv
37、al += dvalival += dval; ;ival += static_cast( dvalival += static_cast( dval ); );3.3.避免出現(xiàn)多種轉(zhuǎn)換可能的歧義情況。避免出現(xiàn)多種轉(zhuǎn)換可能的歧義情況。第10章其他2022-6-2831n dynamic_castdynamic_cast一般一般被用來執(zhí)行從基類指針到派生類指針被用來執(zhí)行從基類指針到派生類指針的安全轉(zhuǎn)換,常常被稱為安全的向下轉(zhuǎn)換。的安全轉(zhuǎn)換,常常被稱為安全的向下轉(zhuǎn)換。是在運行時是在運行時刻執(zhí)行的。失敗返回刻執(zhí)行的。失敗返回0 0。manager manager * *pm = dynamic_ca
38、st managerpm = dynamic_cast( pe ( pe ); );n const_castconst_cast將轉(zhuǎn)換掉表達式的常量性,例如:將轉(zhuǎn)換掉表達式的常量性,例如:extern char extern char * *string_copystring_copy( char( char* * ); );const char const char * *pc_strpc_str; ;char char * *pc = string_copypc = string_copy( ( const_castconst_cast char ( pc_str( pc_str ); )
39、;n reinterpre_castreinterpre_cast通常對于操作數(shù)的位模式執(zhí)行一個比通常對于操作數(shù)的位模式執(zhí)行一個比較低層次的重新解釋,例如:較低層次的重新解釋,例如:complex complex * *pcom;pcom;char char * *pc = reinterpret_cast charpc = reinterpret_cast( pcom ); ( pcom );第10章其他2022-6-2832n 舊式強制類型轉(zhuǎn)換舊式強制類型轉(zhuǎn)換char char * *pc = pc = (char(char* *) ) pcom pcom; ;/C/C風格風格int iv
40、alint ival = = (int(int) ) 3.14159; 3.14159;/C/C風格風格int addr_valueint addr_value = = intint( &ival( &ival ); );/C+/C+風格風格第10章其他2022-6-2833n C+C+提供了一種機制,通過它,每個類都可以定義一組提供了一種機制,通過它,每個類都可以定義一組可被應用在該類型對象上的轉(zhuǎn)換??杀粦迷谠擃愋蛯ο笊系霓D(zhuǎn)換。n 轉(zhuǎn)換函數(shù)轉(zhuǎn)換函數(shù)(conversion function)(conversion function)是一種特殊類型的類是一種特殊類型的類成員函數(shù)
41、,它定義了一個由用戶定義的轉(zhuǎn)換,以便把一成員函數(shù),它定義了一個由用戶定義的轉(zhuǎn)換,以便把一個類對象轉(zhuǎn)換成某種其他的類型。在類體中通過指定關個類對象轉(zhuǎn)換成某種其他的類型。在類體中通過指定關鍵字鍵字operatoroperator,并在其后加上轉(zhuǎn)換的目標類型后我們就,并在其后加上轉(zhuǎn)換的目標類型后我們就可以聲明轉(zhuǎn)換函數(shù)??梢月暶鬓D(zhuǎn)換函數(shù)。n 轉(zhuǎn)換函數(shù)又稱類型強制轉(zhuǎn)換成員函數(shù),它是類中的一個轉(zhuǎn)換函數(shù)又稱類型強制轉(zhuǎn)換成員函數(shù),它是類中的一個非靜態(tài)成員函數(shù)。它的定義格式如下:非靜態(tài)成員函數(shù)。它的定義格式如下:第10章其他2022-6-2834class class 1 public:public:opera
42、tor operator ();2(); n 這個轉(zhuǎn)換函數(shù)定義了由這個轉(zhuǎn)換函數(shù)定義了由 1到到 2之間的映射關系。之間的映射關系。 2可以是可以是內(nèi)置類型、類內(nèi)置類型、類類型或類型或typedeftypedef。下面通過一個例子說明轉(zhuǎn)換函數(shù)的功。下面通過一個例子說明轉(zhuǎn)換函數(shù)的功能。能。第10章其他2022-6-2835class Rationalclass Rationalpublic:public:Rational(int d, intRational(int d, int n) n)den = d;den = d;num = n;num = n; operator double(); /o
43、perator double(); /類型轉(zhuǎn)換函數(shù)類型轉(zhuǎn)換函數(shù)private:private:intint den, num; den, num;Rational:operatorRational:operator double() double()return double(den)/double(numreturn double(den)/double(num);); intint main() main() Rational r(5, 8);Rational r(5, 8);double d = 4.7;double d = 4.7;d+=r;d+=r;coutdendlcoutdend
44、l; ;return 0;return 0; 第10章其他2022-6-2836n 程序輸出結(jié)果:程序輸出結(jié)果:5.3255.325n 由程序可知,由程序可知,d d是一個是一個doubledouble型數(shù)值,型數(shù)值,r r是是RationalRational類的類的對象,這兩個不同類型的數(shù)據(jù)進行加法之所以能夠進行對象,這兩個不同類型的數(shù)據(jù)進行加法之所以能夠進行是得益于轉(zhuǎn)換函數(shù)是得益于轉(zhuǎn)換函數(shù) operator double()operator double()。為使上述加法。為使上述加法能夠進行,編譯系統(tǒng)先檢查類能夠進行,編譯系統(tǒng)先檢查類RationalRational的說明,看是否的說明,
45、看是否存在在下轉(zhuǎn)換函數(shù)能夠?qū)⒋嬖谠谙罗D(zhuǎn)換函數(shù)能夠?qū)ationalRational類型的操作數(shù)轉(zhuǎn)換為類型的操作數(shù)轉(zhuǎn)換為 doubledouble類型的操作數(shù)。由于類型的操作數(shù)。由于RationalRational類中說明了轉(zhuǎn)換函類中說明了轉(zhuǎn)換函數(shù)數(shù)operator double()operator double(),它可以在程序運行時進行上述,它可以在程序運行時進行上述類型轉(zhuǎn)換,因此,該程序中實現(xiàn)了類型轉(zhuǎn)換,因此,該程序中實現(xiàn)了d+=r;d+=r;的操作。的操作。第10章其他2022-6-2837n 定義轉(zhuǎn)換函數(shù)時應注意如下幾點:定義轉(zhuǎn)換函數(shù)時應注意如下幾點:1.1.轉(zhuǎn)換函數(shù)是用戶定義的成員函
46、數(shù),但它要是非靜態(tài)的。轉(zhuǎn)換函數(shù)是用戶定義的成員函數(shù),但它要是非靜態(tài)的。2.2.轉(zhuǎn)換函數(shù)的名稱是類型轉(zhuǎn)換的目標類型,因此,不必再轉(zhuǎn)換函數(shù)的名稱是類型轉(zhuǎn)換的目標類型,因此,不必再為它指定返回值類型。為它指定返回值類型。3.3.轉(zhuǎn)換函數(shù)是被用于本類型的數(shù)值或變量轉(zhuǎn)換為其他的類轉(zhuǎn)換函數(shù)是被用于本類型的數(shù)值或變量轉(zhuǎn)換為其他的類型,也不必帶參數(shù)。型,也不必帶參數(shù)。4.4.轉(zhuǎn)換函數(shù)函數(shù)還不能定義為友元函數(shù)。轉(zhuǎn)換函數(shù)函數(shù)還不能定義為友元函數(shù)。5.5.不能定義到不能定義到voidvoid的轉(zhuǎn)換,也不允許轉(zhuǎn)換成數(shù)組或者函數(shù)的轉(zhuǎn)換,也不允許轉(zhuǎn)換成數(shù)組或者函數(shù)類型。類型。6.6.轉(zhuǎn)換常定義為轉(zhuǎn)換常定義為constco
47、nst形式,原因是它并不改變數(shù)據(jù)成員形式,原因是它并不改變數(shù)據(jù)成員的值。的值。第10章其他2022-6-2838n 轉(zhuǎn)換操作符過于強大,它可以定義到一種內(nèi)置類型的轉(zhuǎn)轉(zhuǎn)換操作符過于強大,它可以定義到一種內(nèi)置類型的轉(zhuǎn)換,然而這種內(nèi)置類型本身是可能繼續(xù)轉(zhuǎn)換成其他的內(nèi)換,然而這種內(nèi)置類型本身是可能繼續(xù)轉(zhuǎn)換成其他的內(nèi)置類型的,如置類型的,如operator intoperator int() const() const定義了到定義了到intint型的型的轉(zhuǎn)換,然后轉(zhuǎn)換,然后intint型可以轉(zhuǎn)換到型可以轉(zhuǎn)換到floatfloat、doubledouble、ongong等類等類型,這樣極不容易確定編譯器為
48、我們做了什么,在出現(xiàn)型,這樣極不容易確定編譯器為我們做了什么,在出現(xiàn)問題后,也極不容易定位錯誤。問題后,也極不容易定位錯誤。n 當類類型定義了一個到基本類型當類類型定義了一個到基本類型A A的轉(zhuǎn)換后,可能在實的轉(zhuǎn)換后,可能在實際中轉(zhuǎn)換到另一基本類型際中轉(zhuǎn)換到另一基本類型B B,如果再定義一個到基本類,如果再定義一個到基本類型型C C的轉(zhuǎn)換,而的轉(zhuǎn)換,而C C也可以轉(zhuǎn)換到也可以轉(zhuǎn)換到B B。這時就會在產(chǎn)生二義。這時就會在產(chǎn)生二義性,如性,如A A為為intint,B B為為long doublelong double,C C為為doubledouble,在產(chǎn)生,在產(chǎn)生自定義類型的對象時,需要轉(zhuǎn)換
49、,就會使得編譯器并不自定義類型的對象時,需要轉(zhuǎn)換,就會使得編譯器并不知道如何處理,到底是調(diào)用哪個轉(zhuǎn)換。知道如何處理,到底是調(diào)用哪個轉(zhuǎn)換。第10章其他2022-6-2839n 使用自定義轉(zhuǎn)換時,定義轉(zhuǎn)換多,會像上述那樣引發(fā)二使用自定義轉(zhuǎn)換時,定義轉(zhuǎn)換多,會像上述那樣引發(fā)二義性。避免的方法是,最好在定義到內(nèi)置類型的轉(zhuǎn)換時義性。避免的方法是,最好在定義到內(nèi)置類型的轉(zhuǎn)換時,只定義一個,因為內(nèi)置類型之間的轉(zhuǎn)換太靈活了。,只定義一個,因為內(nèi)置類型之間的轉(zhuǎn)換太靈活了。n 另外,構(gòu)造函數(shù)和轉(zhuǎn)換函數(shù)之間也可能存在二義性。后另外,構(gòu)造函數(shù)和轉(zhuǎn)換函數(shù)之間也可能存在二義性。后面會講到。面會講到。第10章其他2022-6-2840n 在一個類的構(gòu)造函數(shù)中,凡是只帶一個參數(shù)的構(gòu)造函數(shù)在一個類的構(gòu)造函數(shù)中,凡是只帶一個參數(shù)的構(gòu)造函數(shù),都定義了一組隱式轉(zhuǎn)換,把構(gòu)造函數(shù)的參數(shù)類型轉(zhuǎn)換,都定義了一組隱式轉(zhuǎn)換,把構(gòu)造函數(shù)的參數(shù)類型轉(zhuǎn)換為該類的類型。為該類的類型。n 如果需要,編譯器會在調(diào)用構(gòu)造函數(shù)執(zhí)行用戶定義的轉(zhuǎn)如果需要,編譯器會在調(diào)用構(gòu)造函數(shù)執(zhí)行用戶定義的轉(zhuǎn)換之前,在實參上應用標準轉(zhuǎn)換序列。換之前,在實參上應用標準轉(zhuǎn)換序列。n 下面通過一個例子進一步說明單參數(shù)構(gòu)造函數(shù)的類型轉(zhuǎn)下面通過一個例子進一步說明單參數(shù)構(gòu)造函數(shù)的類型轉(zhuǎn)換功能。換功能。第10章其他2022-6-
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- T-ZZB 3633-2024 原液著色滌綸牽伸絲
- T-ZSM 0074-2024 餐飲業(yè)油煙排放在線監(jiān)測儀
- 二零二五年度旅游行業(yè)客服業(yè)務員雇傭服務協(xié)議
- 二零二五年度總經(jīng)理社會責任與公益慈善聘用協(xié)議
- 2025年度模特時尚活動贊助商權(quán)益合作協(xié)議
- 二零二五年度荒山承包轉(zhuǎn)讓及林業(yè)資源開發(fā)利用合同
- 二零二五年度學校事業(yè)單位校車司機勞動合同
- 二零二五年度私人土地買賣合同案:森林資源開發(fā)合作合同樣本
- 二零二五年度學生校園交通安全管理協(xié)議范本匯編
- 二零二五年度合作社職業(yè)經(jīng)理人鄉(xiāng)村振興聘用協(xié)議
- 棗莊學院《電力拖動與自動控制系統(tǒng)》2023-2024學年第一學期期末試卷
- 2024年江蘇經(jīng)貿(mào)職業(yè)技術學院單招職業(yè)適應性測試題庫
- 綠化遷移專項施工方案
- 2025屆高三化學一輪復習 原電池 化學電源(第一課時)課件
- 全院護理查房(食管裂孔疝)
- 2024-2025學年統(tǒng)編版語文九年級下冊第7課《溜索》任務驅(qū)動型教學設計
- 2023-2024學年五年級科學下冊(冀人版)第4課露和霜(教學設計)
- 《管理學》第一章-管理導論
- 2024年國考公務員行測真題及參考答案
- 二手車交易定金合同范本5篇
- NB∕T 10391-2020 水工隧洞設計規(guī)范
評論
0/150
提交評論