華為C++中級(jí)培訓(xùn)教材_第1頁(yè)
華為C++中級(jí)培訓(xùn)教材_第2頁(yè)
華為C++中級(jí)培訓(xùn)教材_第3頁(yè)
華為C++中級(jí)培訓(xùn)教材_第4頁(yè)
華為C++中級(jí)培訓(xùn)教材_第5頁(yè)
已閱讀5頁(yè),還剩34頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

附件三:教材模板說明:一、為便于保存和管理,各類培訓(xùn)教材均采用合訂本。二、教材結(jié)構(gòu):各類培訓(xùn)教材由教材封面、前言、課程目錄、單門課程教材和封底五部分構(gòu)成。三、教材封面:1、封面顏色:教材封面為彩色,工作基本常識(shí)教材為深藍(lán)色,技術(shù)基礎(chǔ)知識(shí)教材為草綠色,管理基礎(chǔ)知識(shí)教材為淺藍(lán)色,營(yíng)銷基礎(chǔ)知識(shí)教材為墨綠色。2、教材名稱:采用“工作基本常識(shí)”“技術(shù)基礎(chǔ)知識(shí)”“管理基礎(chǔ)知識(shí)”“營(yíng)銷基礎(chǔ)知識(shí)”,字體為隸書,黑體,60號(hào)。3、其他標(biāo)識(shí):?jiǎn)T工培訓(xùn)中心編輯采用宋體、黑體、三號(hào),位于教材名稱下面;華司和員工培訓(xùn)中心編輯之間;右上角為保密標(biāo)識(shí),楷體,黑體,四號(hào)。四、教材封底:面的右下角。五、前言:教材前言為各類培訓(xùn)的目的、課程門類、特點(diǎn)、主要內(nèi)容的簡(jiǎn)介。六、課程目錄:為各門課程排列順序的目錄,統(tǒng)一編排頁(yè)碼,便于學(xué)員查找。七、單門課程教材:和相關(guān)網(wǎng)站組成。1、課程封面:課程封面為彩色,課程名稱為隸書、60號(hào)、黑體、黑色,左上角為課程編碼。2、章節(jié)目錄:為宋體、小四、黑色3、章節(jié)內(nèi)容:1小四、黑體。字一般為宋體、小四、黑色,行間距為一行半。(3)內(nèi)容:章節(jié)內(nèi)容要有完整的理論體系,不能成為授課膠片的翻版。4、學(xué)習(xí)要求:每章標(biāo)題下面為本章的學(xué)習(xí)要求,以明確本章要掌握的要點(diǎn)。文字為楷體、小四。5、思考題:每章最后要有思考題,以便幫助學(xué)員復(fù)習(xí)、思考。6、參考資料和相關(guān)網(wǎng)站:有參考資料和相關(guān)網(wǎng)站的要附在課程后面,以便幫助學(xué)員查閱。2內(nèi)部資料,注意保密C++中級(jí)培訓(xùn)教程員工培訓(xùn)中心編輯2005年6月V1.0華為技術(shù)華為技術(shù)有限公司3前言C++語(yǔ)言中級(jí)教材講授C++語(yǔ)言的運(yùn)用技術(shù),包括:類、對(duì)象之間C++模式設(shè)計(jì)基本思想。4NE002009cV1.01業(yè)務(wù)與軟件C++語(yǔ)言項(xiàng)目C++進(jìn)階5目錄第一章類、接口…………………71.1Handle-Body與接口、抽象接口…………71.2多繼承、與菱形缺陷、this跳轉(zhuǎn)等………131.3C++多態(tài)的兩種多態(tài)形式和區(qū)別……………18第二章重載………………………182.1函數(shù)重載………………………192.2運(yùn)算符重載…………………20第三章模板………………………293.1模塊函數(shù)……………………293.2模塊類……………313.3STL標(biāo)準(zhǔn)模板庫(kù)…………………34附錄:參考資料………………………396ISC基本知識(shí)附錄:名詞解釋前言我們?cè)贑++基礎(chǔ)課程中已經(jīng)了解了C++的一些基本概念,知道了什么是類什么是對(duì)象。也了解了繼承、封裝、多態(tài)等C++面向?qū)ο蟮幕咎卣?,本課程主要是更進(jìn)一步探討一下C++一些基本模型的應(yīng)用,加深對(duì)概念的理解,由于課程時(shí)間有限,C++,模型和內(nèi)容又如此之多,對(duì)任何一個(gè)模型都無法深入進(jìn)去,所以只能泛泛而談。第一章類、接口學(xué)習(xí)要求:1、了解類的繼承、封裝等概念之間的關(guān)系2特點(diǎn)。學(xué)會(huì)使用接口編程的思想本章節(jié)主要介紹C++的行為。有關(guān)類的基本概念:ClassnamesClassmembersMemberFunctionsStaticMemberFunctionsUnionsC++BitFieldsNestedClassDeclarationsTypeNamesinClassScopeMultipleBaseClassesVirtualFunctionsAbstractClassesControllingAccesstoClassMembersprivateMembersprotectedMemberspublicMembers7ISC基本知識(shí)附錄:名詞解釋AccessSpecifiersforBaseClassespriavtepublicprotectedFriendsConstructorsDestructorsConversionFunctionsthenewoperatorandthedeleteoperatorCopyingConstructorFunctionsInterface1.1Handle-Body與接口、抽象接口在C++但是C++實(shí)現(xiàn)部分隱藏起來。C++在編譯期間要盡可能多地做靜態(tài)類型檢查。這意味著盡早捕獲錯(cuò)誤,也意味著程序具有更高的效率。然而這對(duì)私有的實(shí)現(xiàn)部分來說帶來兩個(gè)影響:復(fù)編譯。然而C++并沒有將這個(gè)原則應(yīng)用到二進(jìn)制層次上,這是因?yàn)镃++的類既是描述了一個(gè)接口同時(shí)也描述了實(shí)現(xiàn)的過程,示例如下:classCMyString{private:constintm_cch;char*m_psz;public:CMyString(constchar*psz);~CMyString();intLength()const;intIndex(constchar*psz)const;}8ISC基本知識(shí)附錄:名詞解釋CMyStirng對(duì)外過多的暴露了內(nèi)存布局實(shí)現(xiàn)的細(xì)節(jié),這些信息過度的依賴于這些成員變的接口不利于跨語(yǔ)言跨平臺(tái)的軟件開發(fā)和移植。1.1.1Handle-Body模式handle1]。有關(guān)實(shí)現(xiàn)的任何東西都消失了,只剩一個(gè)單一的指針“m_pThis”。該指針指向一個(gè)結(jié)文件進(jìn)行重新編譯,然后再連接到項(xiàng)目中。指定的類指針。classCMyStringHandle{private:classCMyString;CMyString*m_pThis;public:CMyStringHandle(constchar*psz);~CMyStringHandle();intLength()const;intIndex(constchar*psz)const;};CMyStringHandle::CMyStringHandle(constchar*psz):m_pThis(newCMyString(psz));{}CMyStringHandle::~CMyStringHandle(){deletem_pThis;9ISC基本知識(shí)附錄:名詞解釋}intCMyStringHandle::Length(){returnm_pThis->Length();}intCMyStringHandle::Index(constchar*psz){returnm_pThis->Index(psz);}這是所有客戶程序員都能看到的。這行classCMyString;器,cheshire是一個(gè)結(jié)構(gòu)的名字,但沒有提供有關(guān)該結(jié)構(gòu)的任何東西。這對(duì)產(chǎn)生一個(gè)對(duì)象。在這種技術(shù)里,包含具體實(shí)現(xiàn)的結(jié)構(gòu)主體被隱藏在實(shí)現(xiàn)文件中。Handle-Body模式,Handle-Body只含有一個(gè)實(shí)體指針,服務(wù)的數(shù)據(jù)成員永遠(yuǎn)被封閉在服務(wù)系統(tǒng)中。Handle-Body模式如下:classHandlem_pThisclass圖1Handle-Body模式(句柄類做為接口)Handle-Body的布局結(jié)構(gòu)永遠(yuǎn)不會(huì)隨著實(shí)現(xiàn)類數(shù)據(jù)成員的加入或者刪除或者修改而導(dǎo)致Handle-Body的修改,即Handle-Body協(xié)議不依賴于C++實(shí)現(xiàn)類的任何細(xì)節(jié)。這就有效的10ISC基本知識(shí)附錄:名詞解釋接口成了它唯一的入口。然而Handle-Body模式也有自己的弱點(diǎn):1、接口類必須把每一個(gè)方法調(diào)用顯示的傳遞給實(shí)現(xiàn)類,這在一個(gè)只有一個(gè)構(gòu)造和一個(gè)析構(gòu)的類來說顯然不構(gòu)成負(fù)擔(dān),但是如果一個(gè)龐大的類庫(kù),它有上百上千個(gè)方法時(shí)候,光是編寫這些方法傳遞就有可能非常冗長(zhǎng),這也增加了出錯(cuò)的可能性。2、對(duì)于關(guān)注于性能的應(yīng)用每一個(gè)方法都得有兩層的函數(shù)調(diào)用,嵌套的開銷也不理想3、由于句柄的存在依然存在編譯連接器兼容性問題。接口和實(shí)現(xiàn)分離的Handle-Body。1.1.2抽象接口Handle-Body解決了編譯器/鏈接器的大部分問題,而C++面向?qū)ο缶幊讨械某橄蠼涌谕瑯邮沁\(yùn)用了“接口與實(shí)現(xiàn)分離”的思想,而采用抽象接口對(duì)于解決這類問題是一個(gè)極其完美的解決方案。1、抽象接口的語(yǔ)言描述:classIMyString{virtualintLength()const=0;//這表示是一個(gè)純虛函數(shù),具有純虛函數(shù)的接口virtualintIndex(constchar*psz)const=0;};2、抽象接口的內(nèi)存結(jié)構(gòu):11ISC基本知識(shí)附錄:名詞解釋classvtprclass::m1class::m2圖2抽象接口的內(nèi)存布局3、抽象接口的實(shí)現(xiàn)代碼:接口:classIMyString{virtualintLength()const=0;//這表示是一個(gè)純虛函數(shù),具有純虛//函數(shù)的接口virtualintIndex(constchar*psz)const=0;};實(shí)現(xiàn):classCMyString:publicIMyString{private:constintm_cch;char*m_psz;public:CMyString(constchar*psz);virtual~CMyString();intLength()const;intIndex(constchar*psz)const;12ISC基本知識(shí)附錄:名詞解釋}從上面采用抽象接口的實(shí)例來看,抽象接口解決了Handle-Body所遺留下來的全部缺陷。抽象接口的一個(gè)典型應(yīng)用:抽象工廠(AbstractFactroy)圖3抽象工廠模式1.2多繼承與菱形缺陷、this跳轉(zhuǎn)等多重繼承是C++語(yǔ)言獨(dú)有的繼承方式,其它幾乎所有語(yǔ)言都秉承了單一繼承的思想。這是因?yàn)槎嘀乩^承致命的缺陷導(dǎo)致的:1.2.1菱形缺陷當(dāng)繼承基類時(shí),在派生類中就獲得了基類所有的數(shù)據(jù)成員副本。假如類B從A1和A2兩個(gè)類多重繼承而來,這樣B類就包含A1、A2類的數(shù)據(jù)成員副本??紤]如果A1、A2都從某基類派生,該基類稱為Base,現(xiàn)在繼承關(guān)系如下:13ISC基本知識(shí)附錄:名詞解釋BaseA1A2B圖4菱形繼承關(guān)系我們C++語(yǔ)言來描述這種繼承關(guān)系:classBase{……};classA1:publicBase{……};classA2:publicBase{……};classB:publicA1,publicA2{……};那么A1、A2都具有Base的副本。這樣B就包含了Base的兩個(gè)副本,副本發(fā)生了重疊,不但增加了存儲(chǔ)空間,同時(shí)也引入了二義性。這就是菱形缺陷,菱形缺陷時(shí)間是兩個(gè)缺陷:1、子對(duì)象重疊2、向上映射的二義性。菱形缺陷的其中一種解決辦法將在C++世界里最廣泛的使用虛擬繼承解決菱形缺陷的應(yīng)用便是標(biāo)準(zhǔn)C++的輸入/輸出iostream;14ISC基本知識(shí)附錄:名詞解釋basic_iosbasic_ostreambasic_iostreamiostream圖5標(biāo)準(zhǔn)C++的輸入/輸出1.2.2多重接口與方法名沖突問題(Siamesetwins)原型”的虛函數(shù)情況就不那么容易了。提出問題:假設(shè)汽車最大速度的接口為ICar,潛艇最大速度的接口為IBoat,有一個(gè)兩棲類ICarIBoat兩種交通工具的最大速度特性,我們定義它的接口為ICarBoat;classICar{virtualintGetMaxSpeed()=0;};classIBoat{virtualintGetMaxSpeed()=0;};我們先對(duì)ICarBoat的接口做一個(gè)嘗試:classCCarBoat{virtualint//既完成ICar//完成IBoat的接口方法?顯然不能夠};15ISC基本知識(shí)附錄:名詞解釋解決問題:顯然上面這個(gè)嘗試根本就無法成功,只用一個(gè)實(shí)現(xiàn)方法,怎么能夠求出這個(gè)ICarBoat速度呢。ICarBoat要返回兩個(gè)答案就必須有兩個(gè)方法了,我們假設(shè)一個(gè)方法是求在陸地上奔跑的速度,名稱為GetCarMaxSpeed();另一個(gè)方法是求在大海上航行的最大速度,名稱為classIXCar:publicICar{virtualintGetMaxSpeed(){GetCarMaxSpeed();}virtualintGetCarMaxSpeed()=0;};classIXBoat:publicIBoat{virtualintGetMaxSpeed(){GetBoatMaxSpeed();}virtualintGetBoatMaxSpeed()=0;};classCCarBoat:publicIXCar,publicIXBoat{virtualintGetCarMaxSpeed(){……16ISC基本知識(shí)附錄:名詞解釋}virtualintGetBoatMaxSpeed(){……}};圖6多重接口與方法名沖突問題1.2.3this跳轉(zhuǎn)this跳轉(zhuǎn)是指的“對(duì)象同一性”問題。或者父類的this指針永遠(yuǎn)相等。即如果有下面的模型:17ISC基本知識(shí)附錄:名詞解釋AB圖7B從A繼承的關(guān)系圖那么對(duì)于一個(gè)已經(jīng)實(shí)例化B類的對(duì)象bObject,永遠(yuǎn)有(B*)&bObject==(A*)&bObject成立。但是在多繼承的世界內(nèi),上面的等式就不能恒成立,對(duì)象的同一性受到了挑戰(zhàn)?;疊類的對(duì)象bObject;(Base*)(A1*)&bObject!=(Base*)(A2*)&bObject成立,當(dāng)這種事情發(fā)生的時(shí)候我們就只能特殊處理了。這種情況在COM應(yīng)用中處處都會(huì)發(fā)生。1.3C++多態(tài)的兩種多態(tài)形式和區(qū)別C++有兩種多態(tài)多態(tài)形式:1、編譯時(shí)刻多態(tài),編譯時(shí)刻多態(tài)依靠函數(shù)重載或者模板實(shí)現(xiàn)2、運(yùn)行時(shí)刻多態(tài)。運(yùn)行時(shí)刻多態(tài)依靠需函數(shù)虛接口實(shí)現(xiàn)第二章重載學(xué)習(xí)要求:1、了解什么是函數(shù)重載,什么是運(yùn)算符重載2、學(xué)會(huì)運(yùn)用智能指針,仿函數(shù)18ISC基本知識(shí)附錄:名詞解釋在新定義C++的內(nèi)嵌運(yùn)算符的方法。有關(guān)重載的基本概念:OverloadedFunctionsOverloadedOperatorsDeclarationMatchingArgumentMatchingArgumentTypesMatchingArgumentCountsMatchingC++UnaryOperatorsBinaryOperatorsSmartPointerFunctionobjects1.1函數(shù)重載函數(shù)重載方法是在當(dāng)前范圍內(nèi)選擇一個(gè)最佳匹配的函數(shù)聲明供調(diào)用該方法者使列順序匹配的符合下面條件的:1、一個(gè)精確匹配的函數(shù)被找到2、一個(gè)參數(shù)只有細(xì)微的差別,幾乎可以忽略不計(jì)的。3、象類似通過子類向父類轉(zhuǎn)化達(dá)到參數(shù)匹配的4、通過正常轉(zhuǎn)化函數(shù)進(jìn)行類型轉(zhuǎn)換,能夠達(dá)到參數(shù)匹配到的。5、通過用戶自定義的轉(zhuǎn)化函數(shù)(如轉(zhuǎn)化運(yùn)算符或者構(gòu)造函數(shù))達(dá)到參數(shù)匹配的6、參數(shù)是采用省略符號(hào)函數(shù)重載的方法基本上有:1、根據(jù)函數(shù)參數(shù)數(shù)據(jù)類型的不同進(jìn)行的重載;2、根據(jù)參數(shù)個(gè)數(shù)的不同進(jìn)行的重載;3、缺省參數(shù)上的重載19ISC基本知識(shí)附錄:名詞解釋我們?cè)谶@里把缺省參數(shù)也稱為一種函數(shù)重載,實(shí)際上它并不是嚴(yán)格意義上的重只能放在函數(shù)聲明中。第四,缺省參數(shù)可以讓聲明的參數(shù)沒有標(biāo)識(shí)符。4、返回值重載特別注意,在C++中并沒有根據(jù)返回返回值的不同進(jìn)行重載的,即我們不能定義這樣的函數(shù):voidf();intf();在C++中這樣的函數(shù)聲明方法是被禁止的,但是我們有時(shí)間可能又需要這樣的重載方法,我們又怎么實(shí)現(xiàn)呢,其實(shí)很簡(jiǎn)單,jiang函數(shù)的參數(shù)進(jìn)行擴(kuò)展,將這個(gè)函數(shù)返回值的數(shù)據(jù)類型,做為擴(kuò)展參數(shù)的數(shù)據(jù)類型來。如下:voidf(void);voidf(int);時(shí)刻并不起到傳值作用,模板中經(jīng)常都應(yīng)用到了這種方法。1.2運(yùn)算符重載你可以重新定義C++現(xiàn)可能以類的成員函數(shù)的形式出現(xiàn),也有可能以全局性的函數(shù)的身份出現(xiàn)。在C++中重載運(yùn)算符的名字為operatorx,在這里x重載operator+定義就可以了,例如:Classcomplex//verysimplifiedcomplex{doublere,im;public:20ISC基本知識(shí)附錄:名詞解釋complex(doubler,doublei):re(r),im(i){};complexoperator+(complex);complexoperator*(complex);};定義了complexdouble

類型的數(shù)據(jù)組成,并定義了這個(gè)復(fù)數(shù)的兩個(gè)方法,加法運(yùn)算complex::operartor+()和乘法運(yùn)算complex::operator*().現(xiàn)在我們就能夠?qū)崿F(xiàn)下面的復(fù)數(shù)表達(dá)式了:voidf(){complexa=complex(1,3.1);complexb=complex(1.2,2);complexc=b;a=b+c;b=b+c*a;c=a*b+complex(1,2);}1.3.1C++可重載的和C++不可重載的運(yùn)算符可重載運(yùn)算符表:OperatorNameTypeOperatorNameType,CommaBinary–>*Pointer-to-memberBinary

selection!LogicalNOTUnary/DivisionBinary!=InequalityBinary/=Division/assignmentBinary21ISC基本知識(shí)附錄:名詞解釋%ModulusBinary<LessthanBinary%=Modulus/assignmentBinary<<LeftshiftBinary&BitwiseANDBinary<<=LeftBinary

shift/assignment&Address-ofUnary<=LessthanorequaltoBinary&&LogicalANDBinary=AssignmentBinary&=BitwiseAND/assignBinary==EqualityBinary()Functioncall—>GreaterthanBinary*MultiplicationBinary>=GreaterthanorBinary

equalto*PointerdereferenceUnary>>RightshiftBinary*=Multiplication/assignBinary>>=RightBinaryshift/assignment+AdditionBinary[]Arraysubscript—+UnaryPlusUnary^ExclusiveORBinary++Increment1Unary^=ExclusiveBinaryOR/assignment+=Addition/assignmentBinary|BitwiseinclusiveORBinary–SubtractionBinary|=BitwiseinclusiveBinaryOR/assignment–UnarynegationUnary||LogicalORBinary––Decrement1Unary~One’scomplementUnary–=Subtraction/assignBinarydeletedelete—–>MemberselectionBinarynew不可重載運(yùn)算符表:OperatorName.Memberselection22ISC基本知識(shí)附錄:名詞解釋.*Pointer-to-memberselection::Scoperesolution?:Conditional#Preprocessorsymbol##Preprocessorsymbol在上面可重載的運(yùn)算符可以看出運(yùn)算符重載共分為兩類:一元運(yùn)算符重載和二元運(yùn)算符重載一元運(yùn)算符重載:在聲明一個(gè)類的非靜態(tài)的一元運(yùn)算符重載函數(shù)時(shí),你必須聲明的形式如下:ret-typeoperatorop()(1)在這里ret-type是指返回?cái)?shù)據(jù)類型op是指一元運(yùn)算符在聲明一個(gè)全局的一元運(yùn)算符重載函數(shù)時(shí),你必須聲明的形式日下:ret-typeoperatorop(arg)(2)在這里ret-type與op和上面的意思一樣,arg是指這個(gè)運(yùn)算符所作用的數(shù)據(jù)類型二元運(yùn)算符重載:在聲明一個(gè)類的非靜態(tài)的二元運(yùn)算符重載函數(shù)時(shí),你必須聲明的形式如下:ret-typeoperatorop(arg)(3)(3)式和二式基本相同arg可以是任何一個(gè)在聲明一個(gè)全局的二元運(yùn)算符重載函數(shù)時(shí),你必須聲明的形式日下:ret-typeoperatorop(arg1,arg2)(4)在這里ret-type與op和上面的意思一樣,arg1,arg2,是指這個(gè)運(yùn)算符所作用兩個(gè)數(shù)據(jù)類型1.3.2幾類特殊的運(yùn)算符重載1、類型轉(zhuǎn)換運(yùn)算符23ISC基本知識(shí)附錄:名詞解釋定義的數(shù)據(jù)類型,如:classCString{……operatorLPCSTR()const;……};應(yīng)用:CStringstr=“12345”;LPCSTRlpsz=str;//此處會(huì)進(jìn)行LPCSTR運(yùn)算曾經(jīng)就是用類型裝換運(yùn)算符重載解決一個(gè)跨平臺(tái)通信的問題。2、bool運(yùn)算符重載重載運(yùn)算符bool時(shí)候,需要注意有很多麻煩和臆想不到的東西template<classT>classtestbool{……operatorbool()constthrow(){returnpT!=0;

}private:T*m_pT;}下面結(jié)果均通過編譯testbool<int>sp1;testbool<std::string>sp2;24ISC基本知識(shí)附錄:名詞解釋if(sp1==sp2)if(sp1!=sp2)boolb=sp1intI=sp1*10;從上面可以看得出bool的表現(xiàn)已經(jīng)遠(yuǎn)遠(yuǎn)超過bool本身了,所以建議大家不要輕易對(duì)bool進(jìn)行重載操作。3、地址運(yùn)算符重載在DCOM應(yīng)用中,我們有一個(gè)重載運(yùn)算符的例子:STDAPICoCreateInstance(

REFCLSIDrclsid,LPUNKNOWNpUnkOuter,

DWORDdwClsContext,REFIIDriid,LPVOID*ppv);我們看最后一個(gè)參數(shù)LPVOID一個(gè)接口的指針。一般情況下我們應(yīng)用如下IUnknown*pUn;CoCreateInstance(…,…,…,…,(void**)&pUn);()然而我們也可以這樣寫:IUnknown*pUn;CComPtrcomPtr(pUn);CoCreateInstance(…,…,…,…,(void**)&comPtr);()之所以能夠這么寫這是因?yàn)镃ComPtr重載了“&”運(yùn)算符,如下:template<classT>classCComPtr{public:…CComPtr(T*lp){if((p=lp)!=NULL)p->AddRef();}…T**operator&()25ISC基本知識(shí)附錄:名詞解釋{ATLASSERT(p==NULL);

return&p;}

private:

T*p;};&comPtr實(shí)際上是得到了一般的情況下,我們并不能對(duì)pUn的地址,所以(5)式和(6)式其實(shí)傳入的參數(shù)是一樣當(dāng)都是傳入了pUn的地址。作,這是因?yàn)椋篈、暴露了封裝對(duì)象的地址,如上面CComPtr對(duì)pUn的封裝其實(shí)不起任何作用,任何時(shí)候我都可以直接訪問和修改pUn指針,這就意味著所有權(quán)的完全喪失,封裝不起任何意義B、對(duì)于unaryoperator&的重載使得重載對(duì)方永遠(yuǎn)無法與STL容器進(jìn)行任何融合,甚至無法參與任何泛型編程。一個(gè)對(duì)象的地址是一個(gè)對(duì)象最基本的概念,在一般情況下,我們并不提倡,也請(qǐng)大家慎用地址運(yùn)算符的重載。4、指針運(yùn)算符重載指針運(yùn)算符,有一個(gè)及其特殊且及其重要的機(jī)制:當(dāng)你對(duì)某個(gè)型別實(shí)施operator-〉而這個(gè)型別并非原生指針時(shí)候:

編譯器會(huì)從這個(gè)型別中找出用戶自定義的續(xù)對(duì)這個(gè)operator-〉返回的結(jié)果實(shí)施operator-〉直到找到一個(gè)原生指針。

這種機(jī)制導(dǎo)致了一個(gè)特有的技術(shù):(preandpostfunctioncalls),

“前調(diào)用”及后調(diào)用技術(shù)。應(yīng)用如下:classCallDoSomething{public:voidDoCall(){TRACE("DoCall\n");}};template<classT>classCallInMutiThread26ISC基本知識(shí)附錄:名詞解釋{classLockProxy{public:LockProxyT*pT):(pT){TRACE("Lock\n"}~LockProxy(){TRACE("UnLock\n"}T*operator->(){return;}private:T*;};public:CallInMutiThread(T*):(pT){}LockProxyoperator->(){returnLockProxy(m_pT);}

private:

T*;

};上面CallDoSomething是函數(shù)調(diào)用,假設(shè)這個(gè)類原來是在單線程中運(yùn)行的,但CallInMutiThread對(duì)原始類進(jìn)行配接使之適應(yīng)與多線程環(huán)境,調(diào)用過程如下:CallDoSomethingDoSomthing;CallInMutiThread<CallDoSomething>MutiThread(&DoSomthing);

MutiThread->DoCall();調(diào)用結(jié)果如下:LockDoCallUnLock27ISC基本知識(shí)附錄:名詞解釋從上面可以看出在調(diào)用CallDoSomething的成員函數(shù)DoCall之前調(diào)用了Lock方法,在調(diào)用結(jié)束后有調(diào)用了UnLock。這就是所謂的“前調(diào)用”和“后調(diào)用”模式均可由此解。重載“-〉”運(yùn)算符,同時(shí)引出了智能指針的概念,參見下頁(yè)。5、括號(hào)運(yùn)算符重載語(yǔ)法特征:primary-expression(expression-list)括號(hào)運(yùn)算符是一個(gè)同“-〉”運(yùn)算符一樣也是一個(gè)及其重要的運(yùn)算符在MSDN上說括號(hào)運(yùn)算符是一個(gè)二元運(yùn)算符,我覺得這個(gè)說法是完全錯(cuò)誤的,在所有C++運(yùn)算符重載中,括號(hào)運(yùn)算符,應(yīng)該是唯一沒有規(guī)定參數(shù)元的個(gè)數(shù)的。它的參數(shù)可以從0個(gè)到N個(gè)。示例:classPoint{public:Point(){_x=_y=0;}Point&operator()(intdx,int){_x+=dx;+=dy;return*this;}private:

int_x,_y;

};調(diào)用如下:Pointpt;

pt(3,2);從上面可以看出,括號(hào)運(yùn)算符,調(diào)用形式如下:object(parameterlist);看起來和函數(shù)的形式是完全一樣的:function(parameterlist);所以根據(jù)這一特點(diǎn)我們稱之為仿函數(shù)。28ISC基本知識(shí)附錄:名詞解釋第三章模板學(xué)習(xí)要求:1、了解什么是模板2、學(xué)會(huì)運(yùn)用模板函數(shù),模版類和STLTemplate稱STL)。STL將templates技術(shù)廣泛應(yīng)用于STL容器和STL算法上,在這一領(lǐng)域template技術(shù)發(fā)揮到了極致。本章介紹C++templates的基本概念和語(yǔ)言特性1.1認(rèn)識(shí)模板1、模板的基本語(yǔ)法是:template<typelist],[arglist>declaration這個(gè)templateclass或者是typename類型。declaration域必須是一個(gè)函數(shù)或者類的聲明。1.4模板函數(shù)語(yǔ)法定義:template<comma-separated-list-of-parameters>function-name(parameterlist){}例如:template<typenameT>inlineTconst&max(Tconst&a,Tconst&b)

{//ifa<bthenusebelseuseareturna<b?b:a;}調(diào)用形式:29ISC基本知識(shí)附錄:名詞解釋1:通過調(diào)用的參數(shù)來識(shí)別模板的各參數(shù)類型MAX(4,4.2);//buttypeoffirstargumentdefinesreturntype2:明確指定參數(shù)的類型:MAX<int,float>(4,4.2);//OK在我們的例子中這個(gè)參數(shù)列表是typenameT,其實(shí)在這里typename是可以用class念,typename表達(dá)了一個(gè)比class更抽象意義上的概念。有如下定義如:classtypenamedef{typedefintINT_TYPE;

};如果這樣表達(dá)是正確的:template<classT>classtesttypename:publictypenamedef{public:typename::INT_TYPE;INT_TYPEm_int;

};但是如果把此處的typename換成class就會(huì)報(bào)錯(cuò)1.4.1重載模板函數(shù)(OverloadingFunctionTemplates)C++匹配調(diào)用。下面這個(gè)簡(jiǎn)單的例子說明了重載模板函數(shù)的方法和過程://maximumoftwointvaluesinlineintconst&(intconst&a,intconst&){return<b?:a;

}//maximumoftwovaluesofanytypetemplate<typenameT>inlineTconst&(Tconst&a,Tconst&){return<b?:a;

}30ISC基本知識(shí)附錄:名詞解釋//maximumofthreevaluesofanytypetemplate<typenameT>inlineTconst&(Tconst&a,Tconst&b,Tconst&){return((a,b),c);

}intmain(){::(7,42,68);//callsthetemplateforthreearguments

::(7.0,42.0);//callsmax<double>(byargumentdeduction)

::('a','b');//callsmax<char>(byargumentdeduction)

::(7,42);//callsthenontemplatefortwoints

::<>(7,42);//callsmax<int>(byargumentdeduction)

::<double>(7,42);//callsmax<double>(noargumentdeduction)

}初始化為同一類型,如:max(7,42)調(diào)用匹配非模板函數(shù)也匹配模板函數(shù)。1.5模板類基本的語(yǔ)法定義:template<comma-separated-list-of-parameters>classclass-name{……};具有缺省參數(shù)的模板定義形式template<typenameT,typenameAlloc=alloc>classclass-name{……};設(shè)計(jì)的思維方法:申明并不一定需要定義:1、申明一個(gè)函數(shù),并不實(shí)現(xiàn)在C++中我們可能因?yàn)榻鼓硞€(gè)缺省函數(shù)的調(diào)用操作而申明該缺省函數(shù),但不定以它,例如:classtestDeclare31ISC基本知識(shí)附錄:名詞解釋{public:testDeclare();};我們對(duì)上面的testDeclare的缺省構(gòu)造函數(shù)進(jìn)行了聲明,但是我們并沒有構(gòu)造函數(shù)的的定義,當(dāng)我們執(zhí)行testDeclaredeclare;上面這個(gè)申請(qǐng)創(chuàng)建一個(gè)對(duì)象的操作會(huì)被編譯系統(tǒng)所禁止當(dāng)然,我們也可以對(duì)缺省的重載運(yùn)算符實(shí)施同樣的手段2、申明一個(gè)函數(shù)而不實(shí)現(xiàn)可能是為了模板函數(shù)的泛化泛化:template<typenameT>

TtestFun();特化:template<>inttestFun{return10;

}3、申明一個(gè)函數(shù)可能僅僅為了獲得特殊某一項(xiàng)功能例如:TMarkT();charTest(TintTest(...);sizeof(MarkT());上面的例子其實(shí)就是求T類的的字節(jié)數(shù),其實(shí)在一般情況下,我們直接寫sizeof(T)以通過上面的例子charTest(T)函數(shù)intTest(...)都是沒有定義的,但是由于sizeof是編譯時(shí)刻的運(yùn)算,所以它并不需要關(guān)心這些函數(shù)是否實(shí)現(xiàn)。?申明一個(gè)類而不實(shí)現(xiàn)例如我們?cè)诮鼓0孱惖姆夯^程中就可以實(shí)現(xiàn)template<typenameT>classtestClass;//泛化只申明template<>32ISC基本知識(shí)附錄:名詞解釋classtestClassint>//特化進(jìn)行實(shí)現(xiàn){};如果我們有testClass<char>test;//error//系統(tǒng)會(huì)調(diào)用泛化時(shí)發(fā)現(xiàn)沒有沒有實(shí)現(xiàn)二產(chǎn)生編譯錯(cuò)誤testClass<int>test;//OK//系統(tǒng)調(diào)用特化故OK1.5.1模板設(shè)計(jì)基本方法、編譯器斷言template<classT,class>{typedefcharsmall;classbig{chardummy[2]};staticsmalltest(staticbigtest(…);staticTmarkT();//函數(shù)定義只是為了得到一個(gè)返回類型public;enum{value=sizeoftest(makT()))==sizeof(Small)};

};B、模板特化template<typenameI,typename>structtestClass{testClass(){count<<,<<endl;}};template<typenameT>structtestClass<T*,T*>{testClass(){count<<,T*"<<endl;}

};C、常數(shù)映射型別template<intv>structtestClass{enum{value=v};

};33ISC基本知識(shí)附錄:名詞解釋、型別映射型別template<typenameT>structtestClass{typedefTOriginalType;

};1.6STL標(biāo)準(zhǔn)模板庫(kù)容器?序列容器–queue不允許遍歷行為?關(guān)聯(lián)容器–set(標(biāo)準(zhǔn))、map(標(biāo)準(zhǔn))、hash_table、RB-tree?通用算法?begin()、end()、size()、empty()、erase(iterator__position)、clear()迭代器迭代器的基本算法?能夠進(jìn)行+、-、++、--、+=、-=、==、!=等運(yùn)算?是一種智能性指針,實(shí)現(xiàn)operator*operator->的重載?根據(jù)迭代器的特點(diǎn),迭代器又稱循環(huán)子迭代器前閉后開區(qū)間[first,last)型別?單向迭代器?可逆迭代器?隨機(jī)迭代器34ISC基本知識(shí)附錄:名詞解釋?迭代器的繼承關(guān)系型別萃取–value_type–difference_type–refrence_type–pointer_type–iterator_category–型別萃取機(jī)–iterator_traits算法?數(shù)值運(yùn)算–power、itoa、accumulate35ISC基本知識(shí)附錄:名詞解釋?基本運(yùn)算–fill、fill_n、swa

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論