C++Primer學(xué)習(xí)筆記概要_第1頁
C++Primer學(xué)習(xí)筆記概要_第2頁
C++Primer學(xué)習(xí)筆記概要_第3頁
C++Primer學(xué)習(xí)筆記概要_第4頁
C++Primer學(xué)習(xí)筆記概要_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、C+ Primer 學(xué)習(xí)筆記第 2 章 變量和基本類型1. 在 命 令 行 下 看 main 函 數(shù) 的 返 回 值 , Unix 為 (echo $?) , Windows 為 (echo %ERRORLEVEL%) 。2. 為了兼容 C 語言, C+ 中所有的字符串字面值都由編譯器自動(dòng)在末尾添加一個(gè)空字 符( null )。3. 多行字面值:在一行的末尾加一反斜線符號( )可將此行和下一行當(dāng)做同一行處 理。4. C+支持兩種初始化變量的形式:復(fù)制初始化和直接初始化。復(fù)制初始化語法用等號(=),直接初始化則是把初始化放在括號中。5. 聲明和定義:聲明不能初始化,也不會(huì)分配空間。在C+語言中,

2、變量必須且僅能定義一次,而且在使用變量之前必須定義或聲明變量。6. 因?yàn)槌A吭诙x后就不能被修改,所以定義時(shí)必須初始化。非const 變量默認(rèn)為extern , const 變量默認(rèn)非extern。7. 引用是別名:必須在定義引用時(shí)進(jìn)行初始化。當(dāng)引用初始化后,只要該引用存在,它就保持綁定到初始化時(shí)指向的對象,不可能將應(yīng)用綁定到另一個(gè)對象。不能定義引用類型的引用。8. const 引用是指向 const 的引用,可以綁定到 const 對象、非 const 對象和右值。非const 引用只能綁定到非const 對象。9. 因?yàn)轭^文件包含在多個(gè)源文件中,所以不應(yīng)該含有變量或函數(shù)的定義。但有三例外:

3、頭文件可以定義類、值在編譯時(shí)就知道的 const 對象和 inline 函數(shù)。第 3 章 標(biāo)準(zhǔn)庫類型1. 不應(yīng)該在頭文件中使用using (namespace ,因?yàn)轭^文件會(huì)影響包含它的源文件。2. 任何存儲(chǔ) string 的 size 操作結(jié)果的變量必須為 string:size_type 類型。特別重要的是,不要把size 的返回值賦值給一個(gè)int 變量。(為什么我測試可以?)3. 當(dāng)進(jìn)行 string 對象和字符串字面值混合連接操作時(shí), +操作符的左右操作數(shù)必須至少有一個(gè)是 string 類型的。4. vector: vector容器內(nèi)的元素可以通過下標(biāo)操作和迭代器進(jìn)行訪問修改,但添加元

4、素 必須通過 vector的方法insert、push_back才行。5. const_iterator vs const 的 iterator : const_iterator 是指迭代器指向的內(nèi)容的值不能改變,用來只讀 vector ; const 的 iterator 是指迭代器不能改變,很少用到。6. 任何改變 vector 長度的操作都會(huì)使已存在的迭代器失效。例如,再調(diào)用 push_bach 之后,就不能再信賴指向 vector 的迭代器的值了。7. string、vector、bitset是由標(biāo)準(zhǔn)庫提供的類型,所以他們都有相應(yīng)的方法;C+提供的內(nèi)置類型int 、數(shù)組、指針等都沒有提

5、供方法。第 4 章 數(shù)組和指針1. 數(shù)組維數(shù)必須用值大于1 的常量表達(dá)式定義,不允許數(shù)組直接復(fù)制和賦值。2. 指針保存 0 值,表明它不指向任何對象,所以刪除指針后置 0 是個(gè)好辦法。3. C+提供了一種特殊的指針類型void*,它可以保存任何類型對象的地址。void*指針只支持幾種有限的操作:與另一個(gè)指針進(jìn)行比較;向函數(shù)傳遞 void* 指針或者從 函數(shù)返回 void* 指針;給另一個(gè)void* 指針賦值。不允許使用 void* 指針操縱它所指向的對象。4. 指向const對象的指針和 const指針:指向 const對象的指針(const int * pi )不能通 過該指針修改指向?qū)ο蟮?/p>

6、值; const 指針( int *const pi )指針本身不能變。指針和引用:引用是別名,必須在定義時(shí)初始化,且定義后不能再綁定到其他對象。5. C 風(fēng) 格 字 符 串 : char 數(shù) 組 , 且 以 null 結(jié) 束 。 char ca='c','+','+','o'char *ca1= " primer; siZeof候會(huì)算上 0, strlen 不會(huì)算上 0。6. 用 new 創(chuàng)建動(dòng)態(tài)數(shù)組: int size=get_size();int *p=new intsize;用delete釋放空間:delete

7、口 p; (口必須,數(shù)組的釋放不同一般指針的釋放)7. int *ip4 :聲明了一個(gè)4 維度的指針數(shù)組int (*ip)4 :聲明了一個(gè)指向數(shù)組的指針,可以迭代二維數(shù)組。第 5 章 表達(dá)式1. sizeof操作符的作用是返回一個(gè)對象或類型名的長度,返回值的類型為size數(shù)組ia 的元素個(gè)數(shù):int size=sizeof(ia)/sizeof(*ia);2. 逗號表達(dá)式是一組由逗號分隔的表達(dá)式,這些表達(dá)式從左向右計(jì)算。逗號表達(dá)式的 結(jié)果是其最右邊表達(dá)式的值。3. 類型轉(zhuǎn)換(分隱式轉(zhuǎn)換和顯式轉(zhuǎn)換)。有四種強(qiáng)制類型轉(zhuǎn)換符: static_cast 、 dynamic_cast 、 const_c

8、ast、 reinterpret_cast 。 dynamic_cast 操作符用于將基類類型對 象的引用或指針轉(zhuǎn)換為同一繼承層次中其他類型的引用或指針。 const_cast 用于轉(zhuǎn) 換掉表達(dá)式的 const 性質(zhì)。 static_cast 能顯式完成編譯器隱式執(zhí)行的任何類型轉(zhuǎn)換。 reinterpret_cast 通常為操作數(shù)的位模式提供較低層次的重新解釋。 舊式強(qiáng)制轉(zhuǎn)換: type (expr) 或 (type) expr 兩種形式。第 6 章 語句1. Switch case: case標(biāo)號必須是 整型常量表達(dá)式(case 3.14:和case ival:就不行)。在switch 內(nèi)部

9、要定義常量,必須用塊結(jié)構(gòu)(防止影響其他case)。2. 標(biāo)準(zhǔn)異常類定義在四個(gè)頭文件中:i. exception 頭文件定義了最常見的異常類,它的類名是exception 。這個(gè)類只通知異常的產(chǎn)生,但不會(huì)提供更多的信息。ii. stdexception 頭 文 件 定 義 了 幾 種 常 見 的 異 常 類 : runtime_error, range_error, overflow_error, underflow_error, logic_error, domain_error ( 參數(shù)的結(jié)果值不存在) , invalid_argument, length_error, out_of_ran

10、geiii. new頭文件定義了 bad_alloc異常類型,提供因無法分配內(nèi)存而由new拋出的異常。iv. type_info 頭文件定義了 bad_cast 異常類型, dynamic_cast 失敗拋出的異常。3. 預(yù)處理器定義了四種在調(diào)試時(shí)非常有用的常量:_ _ FILE_ _ 文件名_ _LINE_ _ 當(dāng)前行號_ _TIME_ _ 文件被編譯的時(shí)間_ _DATE_ _文件被編譯的日期第 7 章 函數(shù)1. 形參的初始化與變量的初始化一樣:如果形參具有非引用類型,則復(fù)制實(shí)參的值; 如果形參為引用類型,則它只是實(shí)參的別名。2. 如果使用引用形參的唯一目的是避免復(fù)制實(shí)參,則應(yīng)將形參定義為

11、const 引用。3. 引用指針的形參: void ptrswap(int *&v1,int *&v2)4. C+程序員傾向與通過傳遞指向容器中需要處理的元素的迭代器來傳遞容器。5. 數(shù)組當(dāng)形參時(shí),非引用 (起始是傳遞指針,能改變數(shù)組的內(nèi)容) 會(huì)忽略數(shù)組第一維。通過引用傳遞數(shù)組:void printValue(int (&arr) 10) (括號是必須的)6. 理解返回引用至關(guān)重要的是:千萬不能返回局部變量的引用。7. 既可以在函數(shù)聲明也可以在函數(shù)定義中指定默認(rèn)實(shí)參。但是,在一個(gè)文件中,只能 為一個(gè)形參指定默認(rèn)實(shí)參一次。通常,應(yīng)在函數(shù)聲明中指定默認(rèn)實(shí)參,并將該聲明 放在

12、合適的頭文件中。8. 內(nèi)聯(lián)函數(shù)應(yīng)該在頭文件中定義,這一點(diǎn)不同于其他函數(shù)。在頭文件中加入或修改內(nèi) 聯(lián)函數(shù)時(shí),使用了該頭文件的所有源文件都必須重新編譯。9. 指向函數(shù)的指針: bool (*pf)(Const string &, Const sting &)( *pf 兩側(cè)的圓括號是必需的)。函數(shù)指針只能通過同類型的函數(shù)或函數(shù)指針或0 值常量表達(dá)式進(jìn)行初始化或賦值。如 bool lengthCompare(Const sting &, Const string&);pf=lengthCompare; 調(diào)用時(shí) 可以:pf( "hi" ,"

13、 bye" (*pf) ("hi" ,"°bye”)第 8 章 標(biāo)準(zhǔn) IO 庫1. I/O 對象不可復(fù)制或賦值,故函數(shù)參數(shù)和返回值只能是I/O 對象的指針或引用。2. 標(biāo)準(zhǔn)庫提供了三種類型的流: iostream , fstream , stringstream ,多次讀取時(shí)要注意 流狀態(tài)的清除。3. 刷新緩存區(qū):使用endl(插入換行符),flush (不添加任何字符),ends (插入null),使用 unitbuf 操作符(cout<<unitbuf<< " result ” <<nounit

14、buf;再就是把輸入輸出綁 定在一起(Cin.tie(&Cout) 。4. 如果程序員需要重用文件流讀寫多個(gè)文件,必須在讀另一個(gè)文件之前調(diào)用 Clear 清 除該流的狀態(tài)。 (其他 IO 流也需要Clear 清除流狀態(tài))5. 字符串流 stringstreasm 可以提供字符串的轉(zhuǎn)化和格式化。const 使用總結(jié)1. const 修飾變量,表示該變量為常量,必須在定義是初始化,之后不能修改它的值。2. const 修飾指針:? const int *ip = &val : ip 是指向 const 對象( int )的指針,即不能通過( *ip )修 改val的值(如果val不

15、是const常量,可以通過其他方式修改 val的值);? int *const ip = &val : ip 是指向 int 對象的 const 指針,即不能修改ip 的值,但( *ip )的值可以修改;? const int *const ip=&val : ip 是指向 const對象的 const 指針。3. Const 修飾函數(shù): const int& op(const int) const? const 修飾返回值,表示返回值不能修改,只有在返回引用類型時(shí)才有效(不能返回局部對象的引用);? const 修飾參數(shù),表示該參數(shù)不能在函數(shù)中修改。需要注意的是參數(shù)是

16、指針的情況,到底是const 指針還是指向 const 對象的指針;? const 修飾函數(shù): const 修飾類的成員函數(shù)時(shí),表示該函數(shù)不能修改類的成員變量。4.第 9 章 順序容器1. 關(guān)聯(lián)容器和順序容器的本質(zhì)區(qū)別在于:關(guān)聯(lián)容器通過鍵 ( key ) 存儲(chǔ)和讀取元素,而順序容器的元素排列次序與元素值無關(guān),是由元素添加到容器里的次序決定。2. 標(biāo)準(zhǔn)庫定義了三種順序容器類型: vector, list 和 deque。 vector 是連續(xù)存儲(chǔ)的,能支持快速隨機(jī)訪問;list不需要連續(xù)存儲(chǔ),所以能在中間快速插入和刪除;deque是雙端隊(duì)列。標(biāo)準(zhǔn)庫還提供了三種容器適配器:后進(jìn)先出的stack、先

17、進(jìn)先出的queue和有優(yōu)先級管理的 priority_queue 。 stack 可以建立在 vector 、 list 、 deque 上, queue 要能提供 push_front 操作,不能建立在 vector 上, priority_queue 要求提供隨機(jī)訪問能力,只能建立在 vector 或 deque 上。3. 定義元素是容器的容器時(shí),必須用空格隔開兩個(gè)相鄰的>符號,以示這是兩個(gè)分開的符號,否則,系統(tǒng)會(huì)認(rèn)為 >>是單個(gè)符號,為右移操作符,并結(jié)果導(dǎo)致編譯時(shí)錯(cuò)誤;example: vector< vector<string> > lines

18、;4. 容器元素類型必須滿足兩個(gè)約束:? 元素類型必須支持賦值運(yùn)算? 元素類型的對象必須可以復(fù)制引用不支持一般意義的賦值運(yùn)算, IO 標(biāo)準(zhǔn)庫類型不支持賦值和復(fù)制操作,所以不 能創(chuàng)建存儲(chǔ)他們的容器。5. 順序容器上的操作? 初始化(適用于關(guān)聯(lián)容器)i. C<T> c 默認(rèn)初始化,創(chuàng)建一個(gè)空的容器ii. C c(c2) 創(chuàng)建容器 c2 的副本c ,兩個(gè)容器的類型和元素類型都必須相同iii. C c(b,e)創(chuàng)建c,其元素是迭代器 b和c標(biāo)示的范圍內(nèi)元素的副本,只要迭代器存儲(chǔ)的值能轉(zhuǎn)化為容器的元素即可,不需要容器類型相同。iv. C c(n,t) / C c(n)創(chuàng)建有n個(gè)值為t(或默認(rèn)

19、值)的容器c,只適用于順序容器。? 向容器內(nèi)添加元素有三類函數(shù) push_back()、push_front()、insert。,用 insert。在指定位置插入單個(gè)元素時(shí), 返回指向新元素的迭代器 ,其他的都返回 void? 容器大小操作size(), max_size(), empty() resize()。 resize。能刪除多出來的元素。? 訪問元素用迭代器迭代容器或者使用下標(biāo)操作( list 不支持下標(biāo)操作)? 刪除元素erase()( 返回指向刪除元素后的迭代器) , clear(), pop_back(), pop_front() (pop_ 操作只刪除元素,不返回刪除的元素值

20、,返回 void )? assign 賦值操作, swap 交換容器操作(不會(huì)破壞迭代器)6. list vs vector deque? list 的元素不是連續(xù)存儲(chǔ),所以不支持隨機(jī)訪問,所以不支持下標(biāo)操作( )和 at()操作,其上的迭代器不支持+n操作和大小比較操作(只支持等于,不等操作)? vector 不支持前端操作( push_front() pop_front() )7. 修改容器時(shí),會(huì)使容器上的迭代器失效。 vector 和 deque 連續(xù)存儲(chǔ),在中間插入刪 除元素時(shí),會(huì)重組織存儲(chǔ)。8. string 類型不支持以棧方式操縱容器; string 支持的其他操作: substr

21、 append replace find rfind find_frist_of compare 。第 10 章 關(guān)聯(lián)容器1. 標(biāo)準(zhǔn)庫提供的關(guān)聯(lián)容器有: map, set, multimap , multiset 。 map 存儲(chǔ)鍵值對, set 存儲(chǔ)單個(gè)鍵, multi 支持同一個(gè)見多次出現(xiàn)。2. pair類型和make_pair函數(shù):對 map上的迭代器解引用是paircont T1, T2對象。3. map、set上的鍵類型,唯一的約束就是必須支持操作符,至于是否支持其他的關(guān)系或相等運(yùn)算,則不做要求。4. map, set, multimap , multiset? 都 支 持 inse

22、rt , count , find , erase 操 作 以 及 lower_bound , upper_bound , equal_range 操作(注意他們的返回值),初始化見順序容器;? 只有 map 支持下標(biāo)操作,而且與下標(biāo)訪問數(shù)組或vector 的行為截然不同:用下標(biāo)訪問不存在的元素將導(dǎo)致在map 容器中添加一個(gè)新元素,它的鍵即為該下標(biāo)值,值為值類型的默認(rèn)初始化值。第 11 章 泛型算法1. 泛型算法中,所謂 “泛型 “指的是兩個(gè)方面:這些算法可作用與各種不同的容器類型,而這些容器又可以容納多種不同的元素。泛型算法必須包含 algorithm 頭文件,算術(shù)算法還必須包含numerc

23、頭文件。插入器(inserter)包含在interator頭文件中。2. 泛型算法的形參模式: alg (beg, end, beg2, end2, other parms)、beg,end標(biāo)記第一個(gè)范圍,這兩個(gè)參數(shù)泛型算法都有;beg2,end2標(biāo)記第二個(gè)范圍,可能沒有這個(gè)兩個(gè)參數(shù); parms 表示其他算法需要的值或謂詞。3. 算法不直接修改容器的大小,如果需要添加和刪除元素,則必須使用容器操作。4. 泛型算法的分類? 只讀算法:只讀輸入范圍內(nèi)的元素,而不會(huì)寫這些元素。 find(), accumulate(), find_first_of() 是只讀算法;? 寫容器元素算法:將數(shù)據(jù)寫入第

24、一或第二輸入范圍。 fill(), fill_n(), copy(), replace() 都是這類算法。直接將元素寫入目標(biāo)很危險(xiǎn),因?yàn)榉盒退惴ú粫?huì)調(diào)用 容器提供的操作(如insert ) (相當(dāng)于用下標(biāo)讀vector 的內(nèi)容,再修改),所以很類算法一般要和插入迭代器配合使用。有三種插入迭代器: back_inserter ,創(chuàng) 建使用 push_back 實(shí)現(xiàn)插入的迭代器; front_inserter ,使用 push_front 實(shí)現(xiàn)插入(不能用在 vector上);inserter,使用insert實(shí)現(xiàn)插入。vector<int> ivec;replace_copy(ili

25、st.begin(), ilist.end(), inserter(ivec,ivec.begin(), 0, 42);? 對容器元素重新排序的算法: sort(), unique()5. 五種迭代器?輸入迭代器:讀,不能寫;只支持自增運(yùn)算。istream_iterator 是輸入迭代器?輸出迭代器:寫,不能讀;只支持自增運(yùn)算。ostream_iterator 是輸出迭代器? 前向迭代器:讀和寫,只支持自增運(yùn)算。 replace 算法需要前向迭代器?雙向迭代器:讀和寫,支持自增和自減運(yùn)算,map、 set、 list 提供雙向迭代器。Reverse 算法需要雙向迭代器? 隨機(jī)訪問迭代器:讀和寫

26、,支持完整的迭代器算術(shù)運(yùn)算, string 、 vector 和 deque提供雙向迭代器。6. list 容器特有的算法list 上提供雙向迭代器,故很多需要隨機(jī)訪問迭代器的算法不能在其上運(yùn)行,故標(biāo)準(zhǔn)庫為 list 容器定義了更精細(xì)的操作集合,如merge(), remove(), sort(), reverse(), splice(), unique()第12章 類1. 在類內(nèi)部定義的成員函數(shù),將自動(dòng)作為 inline 處理。也可以顯式的將成員函數(shù)聲明 為 inline 。 inline 成員函數(shù)的定義必須在調(diào)用該函數(shù)的每個(gè)源文件中是可見的,故 inline 函數(shù)的定義通常放在定義該類的頭

27、文件中。2. 類聲明:為了在類定義之前使用它,我們可以先聲明它,此時(shí)該類稱為不完全類型。不完全類型只能以有限訪問時(shí)用。不能定義該類型的對象。不完全類型只能用 于定義指向該類型的指針及引用,或者用與聲明(而不是定義)使用該類型作為形 參類型或返回類型的函數(shù)。類的聲明一般用來編寫相互依賴的類。3. 可以把數(shù)據(jù)成員聲明為mutable (不能同時(shí)為const修飾),mutable數(shù)據(jù)成員可以在const 成員函數(shù)中修改。4. 當(dāng)成員函數(shù)的返回類型在類中定義時(shí),而且是在類外定義的,則定義時(shí)需要使用完 全限定名。5. 構(gòu)造函數(shù)不能聲明為const。必須又任何const或引用類型成員以及沒有默認(rèn)構(gòu)造函數(shù)的

28、類類型的任何成員使用初始化式。使用構(gòu)造函數(shù)初始化列表初始化,數(shù)據(jù)成員被初始化的次序就是類定義成員的次序,而不是在構(gòu)造函數(shù)初始化列表中的次序。6. 使用默認(rèn)實(shí)參的構(gòu)造函數(shù)能減少代碼重復(fù)。7. 只有當(dāng)一個(gè)類沒有定義構(gòu)造函數(shù)時(shí),編譯器才會(huì)自動(dòng)生成一個(gè)默認(rèn)構(gòu)造函數(shù)。8. 隱式類類型轉(zhuǎn)換:可以用單個(gè)實(shí)參調(diào)用的構(gòu)造函數(shù),定義了從形參類型到該類類型的一個(gè)隱式轉(zhuǎn)換。可以將構(gòu)造函數(shù)聲明為 explicit ,來防止隱式轉(zhuǎn)換。 explicit 只能 用于類內(nèi)部聲明上(不能用于定義上)。9. 注意友元聲明的順序:聲明類 A ,把類 A 聲明為 B 的友元(在類B 的定義中),定義類 A (需要用到 B 的定義)。

29、10. static 類成員? static 成員函數(shù)不是任何對象的組成部分,故沒有this 形參,可以直接使用類的static 成員,但不能直接使用非static 成員,不能被聲明為 const 和虛函數(shù)。可以使用類作用域操作符從類中直接調(diào)用 static 成員,也可以通過對象調(diào)用。? static 數(shù)據(jù)成員必須在類定義體的外面定義(正好一次),不能通過類構(gòu)造函數(shù)初始化,而是應(yīng)該在外面定義時(shí)初始化。 static 關(guān)鍵值只能用于類定義體內(nèi)部的聲明中,定義時(shí)不能標(biāo)示為 static 。 const static 數(shù)據(jù)成員可以在類的定義體中初始化,但仍必須在類的定義體外部定義(不必再指定初始化值

30、)。? static 成員不同與非static 成員的使用: static 數(shù)據(jù)成員的類型可以是該成員所屬的類類型( Class Bar static Bar mem; ),非 static 成員被限定聲明為其自身類對象的指針或引用(因?yàn)檫@時(shí)類還沒定義完,相當(dāng)于類的向前聲明);同樣,static 數(shù)據(jù)成員可以作默認(rèn)實(shí)參,非static 不能 (因?yàn)樗荒塥?dú)立于所屬對象) 。第 13 章 復(fù)制控制1. 復(fù)制控制函數(shù)包括復(fù)制構(gòu)造函數(shù)、賦值操作符、析構(gòu)函數(shù)? 復(fù)制構(gòu)造函數(shù):只有單個(gè)參數(shù),而且該形參是對本類類型對象的引用(常用const 修飾),如 T(const T&) 。如果沒有定義復(fù)制構(gòu)

31、造函數(shù)(即使定義了其他構(gòu)造函數(shù)),編譯器會(huì)為我們合成一個(gè) 執(zhí)行逐個(gè)成員初始化,將新對象初始化為原對象的副本。所以為了防止復(fù)制,類必須顯式聲明其復(fù)制構(gòu)造函數(shù)為private。不允許復(fù)制的類對象只能作為引用或指針傳遞給函數(shù)或從函數(shù)返回,也不能用作容器的元素。? 賦值操作符:就是重載 =操作符,如T& operator=(const T&) (注意返回值為類的引用,因?yàn)?返回左操作符) 。合成賦值操作符,將右操作數(shù)對象的每個(gè)成員賦值給左操作數(shù)對象的對應(yīng)成員,還能對數(shù)組賦值。復(fù)制和賦值常一起使用。? 析構(gòu)函數(shù):構(gòu)造函數(shù)的互補(bǔ),釋放對象獲得的資源。 合成構(gòu)造函數(shù)不會(huì)自動(dòng)刪除指針對象所指向

32、的對象。 如果類需要析構(gòu)函數(shù),則它也需要賦值操作符和復(fù)制構(gòu)造函數(shù),這是一個(gè)有用的經(jīng)驗(yàn)法則,常稱為 三法則 ( rule of three) 。析構(gòu)函數(shù)與復(fù)制構(gòu)造函數(shù)或賦值操作符之間的一個(gè)重要區(qū)別是:即使我們編寫了自己的析構(gòu)函數(shù),合成析構(gòu)函數(shù)仍然運(yùn)行。2. 管理指針成員:包含指針的類需要特別注意復(fù)制控制,原因是復(fù)制指針時(shí)只復(fù)制指針中的地址,而不會(huì)復(fù)制指針指向的對象。? 默認(rèn)(合成)復(fù)制/ 賦值管理指針,指針共享同一對象,可能出現(xiàn)懸垂指針。? 用智能指針管理指針復(fù)制 / 賦值:新定義一個(gè)類管理指針,并增加一個(gè)計(jì)數(shù)功能,當(dāng)復(fù)制/賦值時(shí)計(jì)數(shù)加一,對象銷毀時(shí)(析構(gòu)函數(shù))減一,當(dāng)計(jì)數(shù)為0 時(shí),釋放指針。?

33、 定義值型類:給指針成員提供值語義,創(chuàng)建一個(gè)新對象。3. 復(fù)制 /賦值操作要考慮自己復(fù)制/賦值自己。第 14 章 重載操作符與轉(zhuǎn)換1. 重載操作符不能創(chuàng)建任何新的操作符,不能改變操作符的優(yōu)先級、結(jié)合性或操作數(shù)數(shù)目。2. 重載操作符的定義i. 形式是保留字operator 后接許定義的操作符符號,如item operator+(const item&, const item&)ii. 重載操作符必須具有至少一個(gè)類類型或枚舉類型的操作符。這條規(guī)則強(qiáng)制重載操作符不能重新定義用于內(nèi)置類型對象的操作符的含義。iii. 重載操作符可以定義為類的成員函數(shù)或非成員函數(shù)i. 作為類成員的重載函數(shù)

34、,其形參看起來比操作數(shù)數(shù)目少1 。作為成員函數(shù)的操作符有一個(gè)隱含的 this 形參,限定為第一個(gè)操作數(shù) (故輸入輸出操作符不能重載為類成員)ii. 操作符定義為非成員函數(shù)時(shí),通常必須將他們設(shè)置為所操作類的友元,以 訪問類的私有變量。3. 重載操作符的設(shè)計(jì)i. 不要重載具有內(nèi)置含義的操作(逗號、取地址、邏輯與、邏輯或等操作通常不重載)ii. 重載操作符是為了使用方便,當(dāng)一個(gè)重載操作符的含義不明顯,或操作很少時(shí),沒必要重載操作符,定義普通函數(shù)就行了。iii. 選擇成員或非成員的實(shí)現(xiàn):賦值(=) 、下標(biāo) ( ) 、調(diào)用 () 、成員訪問 (->) 、轉(zhuǎn)換操作符等操作必須定義為成員;輸入和輸出操

35、作符必須定義為非成員;對等的操作符,如算法操作符、相等操作符、關(guān)系操作符和位操作符等對稱的操作符,最好定義為非成員;改變對象狀態(tài)或與給定類型緊密聯(lián)系的一些操作符,如自增、自減和解引用,通常定義為類成員。4. 輸出操作符通常應(yīng)進(jìn)行最小限度的格式化,不應(yīng)該輸出換行符;輸入操作符必須處理錯(cuò)誤和文件結(jié)束的可能性,如果可能,要確定錯(cuò)誤回復(fù)措施,保證數(shù)據(jù)是內(nèi)在一致的。5. 重載操作符需要注意返回值的類型:輸入、輸出操作符返回對第一個(gè)參數(shù) (流對象)的引用;加法( + ) 操作符返回新建的對象,自增、自減對象也是返回新建的對象;復(fù)合操作符、賦值操作符返回第一個(gè)操作數(shù)的引用;下標(biāo)( )操作符返回對應(yīng)下標(biāo)內(nèi)容的

36、引用;解引用( * )返回對象的引用;箭頭( -> )操作符一般返回指向?qū)ο蟮闹羔槨?. 讀且返回引用的操作符,如下標(biāo)、箭頭、解引用等,應(yīng)該提供 const 版本和非 const 版本7. 自增、自減操作符:為了區(qū)別前綴和后綴,后綴式操作符函數(shù)接受一個(gè)額外的(無用的) int 型形參,如 item operator+(int) 為后綴式。8. 調(diào)用操作符和函數(shù)對象i. 調(diào)用操作符的定義: int operator() (int val) ,調(diào)用看起來像個(gè)函數(shù)調(diào)用:int value=item(10) 。定義了調(diào)用操作符的類,其對象稱為 函數(shù)對象 ,函數(shù)對象比函數(shù)更靈活,因?yàn)樗鼈兛梢愿淖兂?/p>

37、員變量(即函數(shù)的參數(shù))ii. 標(biāo)準(zhǔn)庫定義了一組算術(shù)、關(guān)系、與邏輯函數(shù)對象類,包含在functional 頭文件中。9. 標(biāo)準(zhǔn)庫定義的函數(shù)對象i. 使用:他們都是模板類, plus<int> intAdd; int sum=intAdd(10,100);ii. 分為一元函數(shù)對象(接受一個(gè)參數(shù))和二元函數(shù)對象iii. 標(biāo)準(zhǔn)庫還定義了函數(shù)適配器來特化和擴(kuò)展函數(shù)對象。 綁定器 : bindlst 和 bind2nd ,綁定一個(gè)參數(shù)到函數(shù)對象的第一個(gè)或第二個(gè)參數(shù); 求反器 : not1 和not2 ,求反一元或二元函數(shù)對象。 not1 ( bind2nd ( less_equal<in

38、t>() , 10 ) )10. 轉(zhuǎn)換操作符:就是定義從類類型的轉(zhuǎn)換(到類類型的轉(zhuǎn)換是構(gòu)造函數(shù))i. 通用形式: operator type()( 通常應(yīng)定義為const) ,返回一個(gè)type 類型的對象 (雖然沒有返回值),這樣類型就可以(默認(rèn))轉(zhuǎn)換為 type 類型。ii. 類類型轉(zhuǎn)換后不能再跟另一個(gè)類類型轉(zhuǎn)換。class A operator B(); class B operator C();A a : B b ; C c;不能直接 c=a,應(yīng)該分成兩步:b=a; c=biii. 轉(zhuǎn)換操作符使用好了能簡潔代碼,但特別容易引起二義性。下面幾條經(jīng)驗(yàn)規(guī)則會(huì)有所幫組:i.不要定義相互轉(zhuǎn)換

39、白類,即如果類Foo具有接受類Bar的對象的構(gòu)造函數(shù),不要再為類Bar 定義到類型Foo 的轉(zhuǎn)換操作符,否則 Foo foo=bar 有二義性11. 避免到內(nèi)置算術(shù)類型的轉(zhuǎn)換。集體而言,如果定義了到算術(shù)類型的轉(zhuǎn)換,則( 1 )不要定義接受算術(shù)類型的操作符的重載版本,讓轉(zhuǎn)換去完成該功能( 2 )不要定義轉(zhuǎn)換到一個(gè)以上算術(shù)類型的轉(zhuǎn)換,讓標(biāo)準(zhǔn)轉(zhuǎn)換提供到其他算術(shù)類型的轉(zhuǎn)換。第 15 章 面向?qū)ο缶幊?. 虛函數(shù) :基類希望派生類重新定義的函數(shù)定義為 virtual 。除了構(gòu)造函數(shù)外,任意非static 成員函數(shù)都可以是虛函數(shù) (一般需要定義虛析構(gòu)函數(shù)) 。保留字 virtual 只在類內(nèi)部的成員函數(shù)聲

40、明中出現(xiàn),不能用在類定義體外部出現(xiàn)的函數(shù)定義上。派生類型必須對想要重定義的每個(gè)繼承成員進(jìn)行聲明,且必須與基類中的定義方式完全匹配(只有一個(gè)例外,返回對基類型的引用或指針,可以變?yōu)榉祷嘏缮愋偷囊没蛑羔槪R坏┖瘮?shù)在基類中聲明為虛函數(shù),它就一直為虛函數(shù)。5. 動(dòng)態(tài)綁定 :動(dòng)態(tài)綁定使編譯器能夠在運(yùn)行時(shí)決定使用基類中定義的函數(shù)還是派生類中定義的函數(shù)。要觸發(fā)動(dòng)態(tài)綁定,必須滿足兩個(gè)條件:第一,只有指定為虛函數(shù)的成員函數(shù)才能進(jìn)行動(dòng)態(tài)綁定;第二,必須通過基類類型的引用或指針進(jìn)行函數(shù)調(diào)用。6. 派生類 :定義派生類形式class classname: access-label base-class? (派生

41、類對基類)訪問權(quán)限: public 和 private 跟其他非繼承對象一樣,關(guān)鍵是protected。 protected 成員可以被派生類對象訪問,但不能被該類型的普通用戶訪問。此外, protected 還有另一重要性質(zhì):派生類只能通過派生類對象訪問其基類的 protected 成員,派生類對其基類類型對象的 protected 成員沒有特殊訪問 權(quán)限。?成員在派生類中的訪問級別:是由成員在基類中的級別,和繼承方式 access-label 共同決定的。如果要恢復(fù)在基類中的訪問級別(只能是public 級另1J),則用 using base-class:(成員名)。? public 派生

42、類繼承基類的接口;使用 private 或 protected 派生的類不繼承基類的接口,這些派生通常稱為實(shí)現(xiàn)繼承。7. 友元關(guān)系不能繼承。8. 即使析構(gòu)函數(shù)沒有工作要做,繼承層次的根類也應(yīng)該定義一個(gè)虛析構(gòu)函數(shù)。9. 通過基類的引用或指針調(diào)用函數(shù),首先在基類中找:如果函數(shù)非虛函數(shù),則直接調(diào)用基類的該函數(shù);如果為虛函數(shù),則看派生類是否重新定義了虛函數(shù),如果定義了,則調(diào)用派生類的方法,不需要管派生類是否進(jìn)行了其他重載(會(huì)屏蔽基類的函數(shù)),這與通過對象調(diào)用不同。10. 純虛函數(shù) :在函數(shù)形參表后面寫上=0 以指定純虛函數(shù)。含有(或繼承)一個(gè)或多個(gè)純虛函數(shù)的類是抽象基類,不能創(chuàng)建抽象類型的對象。11.

43、 容器與繼承 :不應(yīng)該用容器保存基類類型的對象,因?yàn)檫@樣會(huì)把派生類中多余的成員切掉,應(yīng)該保存基類類型的指針(引用不能一般意義的賦值,不能保存在容器中)。指針的復(fù)制和賦值需要特別小心,句柄類就是用來存儲(chǔ)和管理基類,以安全的進(jìn)行指針的復(fù)制和賦值。第 16 章 模板與泛型編程12. 泛型編程 就是以獨(dú)立于任何特定類型的方式編寫代碼。13. 模板定義 : template <class T> (inline) T min() 。要定義為內(nèi)聯(lián)函數(shù), inline 必須放 在 template 后。模板形參可以是表示類型的類型形參,也可以是表示常量表達(dá)式的非類型形參, 非類型模板實(shí)參必須是編譯

44、時(shí)常量表達(dá)式 。14. 模板形參不能為空。模板形參的名字不能在模板內(nèi)部重用。聲明必須指出函數(shù)或類是一個(gè)模板(帶上template )。15. 用 typename 在模板定義內(nèi)部指定類型:如 T:Y 既可能是類型也可以是數(shù)據(jù)成員,為了顯式指定為類型,可以使用: typename T:Y 。16. 類型形參的實(shí)參受限轉(zhuǎn)換 :類型為模板形參的那些實(shí)參轉(zhuǎn)換受限,類型必須完全匹配。17. 函數(shù)模板的顯式實(shí)參 :當(dāng)模板實(shí)參推斷不能確定模板類型時(shí),需要顯式指定模板形參所用的類型或值。 template <class T1, class T2, class T3) T1 sum(T2,T3); 此時(shí)需

45、要顯式指定 T1 , long val=sum<long> (i,lng) 。 (顯式模板實(shí)參從左到右與對應(yīng)模板相匹配。) 顯式實(shí)參后可以類型轉(zhuǎn)換: sum<double,double,double>(intVale,floatVale)18. 標(biāo)準(zhǔn) C+ 為編譯模板代碼定義了兩種模型: 包含編譯模型和 分別編譯模型。 包含編譯模型:在聲明模板的頭文件中添加一條#include ,引入包含相關(guān)定義的源文件。分別編譯模型:定義模板時(shí),在 template 之前包含關(guān)鍵字export 實(shí)現(xiàn)。19. 在 類 外 定 義 類 的 成 員 函 數(shù) 的 開 頭 應(yīng) 該 是 : te

46、mplate <class T> ret-type Queue<T>:member-name 。20. 類模板中的友元聲明i. 普通友元:以非模板函數(shù)或非模板類為模板類的友元,跟普通的一樣ii. 一般模板友元關(guān)系:template<class Type> class Bartemplate<class T> friend class Fool;/ 一對多的關(guān)系template<class T> friend void function(cons T&);/ 一對多的關(guān)系iii. 特定的模板友元關(guān)系tempalte<cla

47、ss Type> class Barfriend class Fool2<Type>friend class Fool<char *>friend void function<Type>(const Type&>21. 模板特化:指定一個(gè)或多個(gè)模板形參的實(shí)際類型或?qū)嶋H值。i. 完全特化(函數(shù)) template<>int compare<const char*>(const char* cosnt &v1,const char* const&v2)(類) template<> class

48、 Queue<const char*,const char*>ii. 類模板部分特化template<class T1> class Queue<T1, const char*>第 17 章 用于大型程序的工具1. 棧展開:用于描訴在查找catch 捕獲拋出異常的函數(shù)過程。在進(jìn)入相應(yīng) catch 之前,撤銷在異常之前構(gòu)造的局部對象。2. 重新拋出:一個(gè)空的throw沒有指定表達(dá)式的 throw 。只有捕獲子句或者從catch 直接或間接調(diào)用的函數(shù)中的重新拋出才有效,其效果是將接到的異常對象重 新拋出。3. 捕獲所有異常的 catch 子句為catch(.)

49、。如果catch(.)與其他catch 子句結(jié)合使用,它必須是最后一個(gè),否則,任何跟在它后面的 catch 子句都將不能被匹配。4. 函數(shù)測試塊:為了處理來自構(gòu)造函數(shù)初始化的異常,必須將構(gòu)造函數(shù)編寫為函數(shù)測 試塊。T:T() try : val(0),str( “ “) catch() 5. 資源分配即初始化:來封裝資源的分配和釋放,可以保證正確釋放資源。這一技術(shù) 常稱為 “資源分配即初始化 “,簡稱 RAII 。6. auto_ptr 類:一個(gè)庫類模板,提供對動(dòng)態(tài)分配對象的異常安全的訪問。不能將 auto_ptr 對象綁定到數(shù)組或變量指針( auto_ptr 釋放資源,會(huì)破還該指針,一般新建 一個(gè)指針給auto_ptr ,如 auto_ptr<string> ap(new string(“t),est ” au)t)o_ptr 對象的復(fù)制和賦值是破壞性操作:將對象的所有權(quán)從右操作數(shù)轉(zhuǎn)到左操作數(shù)。對 auto_ptr 對 象進(jìn)行復(fù)制刪除左操作數(shù)中的對象,因此

溫馨提示

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

最新文檔

評論

0/150

提交評論