1.標準庫只用iostate表示流的狀態,包括badbit,failbit,eofbit,goodbit,通常我們使用good()操作來確定流的狀態正常,使用fail()操作來確定流出錯,實際上將流當做條件使用的代碼就等價于!fail(),而eof和bad只能表示特定的錯誤,
2.為了將檔案流關聯到另外一個檔案,必須首先關閉已經關聯的檔案,否則檔案流的failbit會被置位,隨后的檔案流操作都會失敗,
3.容器的begin()和end()成員都是多載過的,包括一個回傳const成員和一個非const成員,因此哪怕不使用cbegin()或cend()也可以回傳const_iterator,
4.容器賦值操作中,swap(c1,c2)通常比c1 = c2快得多,統一使用非成員版本的swap是一個好習慣,
5.順序容器中(除了array)有一個成員函式assign(),一般對容器物件的賦值操作要求相同的型別,但是使用assign()可以將迭代器范圍,初始化串列等拷貝到順序容器中,即順序容器的初始化時允許的操作,
6.容器的關系運算子左右兩邊運算物件必須是相同型別的容器,其中相等運算子==是使用元素的==運算子實作,其它關系運算子(無序關聯容器沒有)使用元素的 < 運算子,
7.不要保存尾后迭代器的值,在需要使用它的時候去呼叫end(),
8.vector的預留空間會隨著元素的加入而擴張,但并不會隨著元素的移除而收縮,
9.改變string的幾個方法,assign(), append(), replace(), insert(),分別為拷貝,追加,替換,插入,引數非常靈活多變,記住前后引數一致即可,即使用下標加長度就統一使用下標加長度,使用迭代器就統一使用迭代器,
10.string常用操作還有子串,搜索,比較,數值轉換,
11容器配接器有三種,分別是stack、queue、priority_queue,其中公共操作有pop,push,top,emplace,
12.泛型演算法是基于迭代器的,并不直接操作容器(本身不會執行容器的操作),因此一般泛型演算法不會改變容器大小,
13.謂詞是一個可呼叫的運算式,其回傳結果是一個能用作條件的值,
14.可呼叫物件一共有四種,分別是:函式指標、成員函式、多載了函式呼叫運算子的類和lambda運算式,
15.lambda沒有默認引數,實引數目永遠和形引數目相等,
16.lambda如果使用值捕獲,那么被捕獲變數的值是在lambda創建時就已經拷貝了,
17.bind可以調整函式的引數,bind的回傳物件可以接受無限個引數,但是只有匹配的引數才是有效的,
18.inserter插入器永遠指向開始時指向的元素,因為每插入一個新元素,它就會遞增然后指向原來的元素,
19.流迭代器可能會有執行緒不安全的問題,(個人感覺)
20.反向迭代器如果呼叫base轉化為普通迭代器,那么它指向的位置會發生變化,例如,因為(begin(), end())和(rbegin(), rend())指向相同的范圍,所以當rend轉為普通迭代器時,會偏移到begin,
21.五類迭代器中,輸入迭代器和輸出迭代器時并列的,單遍掃描,只能遞增,前向迭代器在它們兩個的基礎上可以多遍掃描,雙向迭代器又增加了遞減的功能,最后隨機訪問迭代器支持所有迭代器操作,
22.鏈表型別(單向和雙向)定義了獨有的sort,merge,remove,reverse和unique,還支持splice操作,優先使用這些成員函式的版本,
23.關聯容器根據 1)map、set 2)是否允許重復值 3)是否有序 這三個維度分為八種不同的關聯容器,
24.有序關聯容器根據關鍵字來排序,如果關鍵字沒有定義<運算子,我們需要自己傳入比較函式(該函式必須滿足嚴格弱序的條件),傳入時需要在模板型別和初始化引數中同時傳入,
25.關聯容器的關鍵字都是const的,
26.C++11以后,可以用{a, b}來構造pair,包括通過{a,b}回傳一個pair等操作,
27.通常不對關聯容器使用泛型演算法,
28.非multi容器進行插入操作時,回傳值是一個pair,包含指向指定關鍵字的元素(容器中的)和一個指示是否插入成功的bool值,而multi容器則直接回傳指向新元素的迭代器,
29.erase通過關鍵字洗掉關聯容器元素時,回傳值是被洗掉元素的個數,
30.只有非const的map和unordered_map支持下標操作和at操作,如果關鍵字對應元素不存在,則下標操作會創建一個新元素,并將關聯值進行值初始化,而at操作還是拋出例外,
31.特別的是,map的下標操作回傳的型別和解參考map迭代器的回傳型別不同,
32.無序容器的底層實作是基于哈希的,在存盤上組織為一組桶,因此無序容器的性能依賴于哈希函式的質量和桶的數量和大小,
33.對于自定義型別別,我們不能直接將其作為無序容器的元素型別,我們需要提供函式來代替==運算子以及哈希值計算函式,類似于有序容器的要求,無序容器的自定義型別別同樣需要在模板引數和初始化引數中傳入自定義的函式,
34.由于shared_ptr只有在參考計數為0時才會銷毀物件并釋放記憶體,所以我們要注意如果確實不再需要某個物件了,要主動銷毀物件,例如泛型演算法重排存放shared_ptr的容器后,無用的元素會在容器尾部,這時我們需要主動呼叫erase洗掉那些不再需要的元素,
35.程式使用動態記憶體出于以下三種原因之一:1)程式不知道自己需要使用多少物件 2)程式不知道所需物件的準確型別 3)程式需要在多個物件間共享資料
36.如果兩個物件共享底層資料,當某個物件被銷毀時,我們不能單方面地銷毀底層資料,
37.new一個物件的時候,哪怕暫時沒有初值,最好也在后面跟一對小括號,這樣對于內置型別來說會值初始化,
38.默認情況下,new如果不能分配所需記憶體,則會拋出bad_alloc的例外,如果我們使用定位new傳入nothrow物件,則相同情況下new會回傳一個空指標,
39.delete的指標必須指向一個動態分配的物件或是一個空指標,(可以接受空指標)
40.使用new和delete的常見問題:1)忘記delete記憶體 2)使用已經釋放掉的物件 3) 同一塊記憶體釋放兩次
41.一旦shared_ptr接管了普通指標指向的物件,就不應該再使用普通指標來訪問該物件了,否則很容易出現空懸指標的問題,
42.使用智能指標的規范:1)不用相同的內置指標初始化(或reset)多個智能指標 2)不delete get()回傳的指標 3)不使用get()初始化或reset另一個智能指標 4)如果使用了reset()回傳的指標,則要注意不能再智能指標釋放記憶體后繼續使用該指標 5)如果管理的資源不是new分配的記憶體,那么要給智能指標傳遞一個對應的洗掉器
43.new T[0]回傳的指標類似于尾后指標,是非空指標,
44.new T[]回傳的并不是陣列型別的物件,而是一個陣列元素型別的指標,因此不能對該物件呼叫begin或end,因為他沒有陣列維度,也不能用范圍for來遍歷該物件內的元素,
45.動態分配的陣列,銷毀時是按逆序銷毀的,即最后一個元素先被銷毀,然后是倒數第二個,以此類推,
46.建構式不能宣告成const,當我們創建一個類的const物件時,直到建構式完成初始化程序,物件才能真正取得其const屬性,因此建構式可以在const物件構造程序中向其寫值,
47.友員的宣告只是指定了權限,而非一個通常意義上的函式宣告,
48.類的定義分為兩部分處理,先編譯成員的宣告,等類全部可見后再編譯函式體,所以宣告中出現的名字必須在使用前確保可見,而函式體則可以使用類中定義的任何名字,
49.定義一個使用默認建構式進行初始化的物件時,不要在物件名之后加空括號對,
50.拷貝建構式被呼叫的三種情況:1)用一個物件初始化另一個物件時,無論使用Type o1(o2)還是Type o1 = o2都呼叫拷貝建構式,2)實參傳遞給形參時(形參非參考),3)函式回傳一個物件時,此時會有一個臨時物件被回傳的物件初始化,函式結束后函式內的物件被釋放,臨時物件用于呼叫者的后續操作,
51.需要解構式的類幾乎肯定也需要一個拷貝建構式和一個拷貝賦值運算子,
52.如果一個類需要一個拷貝建構式,那幾乎可以肯定它也需要一個拷貝賦值運算子,反之亦然,
53.如果一個類有資料成員不能被默認構造、拷貝、賦值或銷毀,則對應的成員函式將被定義為洗掉的,
54.賦值運算子應該注意處理自賦值的情況
55.大多數賦值運算子組合了解構式和拷貝建構式的作用,
56.使用copy and swap來定義賦值運算子解決了上面的兩個問題(自賦值和重復拷貝構造、析構的代碼冗余),并且天然就是例外安全的,但是如果swap操作很繁瑣,有很多除了swap資料成員之外的調整操作,那么用copy and swap就得不償失了,
57.右值參考只能系結到臨時物件(右值)上,所以使用右值參考的代碼可以自由地接管所參考物件的資源,
58.因為變數運算式都是左值(即只有一個變數而沒有運算子),所以我們無法將右值參考系結到一個右值參考型別的變數上,右值參考本身是一個左值,
59.不拋出例外的移動建構式和移動賦值運算子必須標記為noexcept,如果不這么做的話,標準庫比如vector在轉移自定義型別元素的時候會選擇更安全的拷貝建構式,
60.在移動操作之后,移后源物件必須保持有效的、可析構的狀態,但是用戶不能對其值做任何假設,
61.通過在類實作代碼中小心地使用std::move,可以大幅度地提升性能,但是在類實作代碼之外的地方,只有在確定需要并保證安全的情況下,才可以使用std::move,
62.通常定義一個const T& 和一個 T&& 的多載函式,
63.參考限定符和const限定符一樣,只能用于非static成員函式,并且必須同時出現在函式的宣告和定義中,如果同時出現了const限定符和參考限定符,則參考限定符必須跟隨在const限定符之后,
64.如果一個成員函式有參考限定符,那么具有相同引數串列的同名函式的所有版本都必須有參考限定符,要么就都不加參考限定符,
65.通常情況下,不應該多載逗號、取地址、邏輯與和邏輯或運算子,
66.賦值(=)、下標([ ])、呼叫(( ))和成員訪問箭頭(->)運算子必須是成員,
67.通常輸出運算子主要負責列印物件內容而非格式,輸出運算子不應該列印換行符,
68.輸入運算子必須處理輸入可能失敗的情況,
69.如果類同時定義了算術運算子和相關的復合賦值運算子,則通常情況下應該使用復合賦值運算子來實作算術運算子,
70.lambda運算式實際上生成了一個匿名的類的匿名物件,其中包含一個多載的函式呼叫運算子,且該多載運算子默認是const的,其值捕獲的資料會變成該物件的資料成員,在生成的建構式中,用捕獲的變數的值來初始化資料成員,
71.標準庫規定其函式物件對于指標同樣適用,
72.有序關聯容器對于關鍵字的排序使用的是函式物件less<key_type>,所以我們可以定義一個指標的map或set而無需直接宣告less,
73.轉換建構式(一個實參)和型別轉換運算子共同定義了型別別轉換,也稱為用戶定義的型別轉換,
74.可以指定explicit將隱式型別轉換運算子指定為顯示,這樣一來就要使用顯示的強制型別轉換來呼叫,但是當包含的物件的運算式用作條件時,編譯器會將顯式的型別轉換(隱式地)應用于它,
75.通常情況下,不要為類定義相同的型別轉換,也不要在類中定義兩個及兩個以上轉換源或轉換目標是算數型別的轉換,否則很可能會產生二義性,
76.除了顯式地向bool型別轉換之外,我們應該盡可能避免定義型別轉換函數并盡可能限制那些“顯然正確”的非顯式建構式,
77.如果某次函式呼叫使用了默認實參,則該實參值由本次呼叫的靜態型別決定,
78.派生類的成員和友員只能訪問派生類物件中的基類部分的受保護成員,對于普通的基類物件中的成員不具有特殊的訪問權限,
79.派生類向基類的轉換,只有在當前的代碼節點可以通過派生類訪問到基類的公有成員時才能進行,否則無法轉換,
80.派生類可以通過using宣告把基類中可訪問的名字標記出來,被標記的名字的訪問權限由該using宣告之前的訪問說明符來決定,
81.基類的作用域在派生類作用域之外,名字查找是從靜態型別所在的作用域開始的,
82.如果建構式或解構式呼叫了某個虛函式,則我們應該執行與建構式或解構式所屬型別相對應的虛函式版本,
83.C++11中派生類可以通過使用using宣告,繼承其直接基類的建構式,
84.模板引數中,系結到非型別整形引數的實參必須是一個常量運算式,系結到指標或參考非型別引數的實參必須具有靜態的生存期,
85.如果一個成員函式沒有被使用,則它不會被實體化,這一特性使得即使某種型別不能完全符合模板操作的要求,依然能用該型別實體化類,
86.在一個類模板的作用域內,我們可以直接使用模板名而不必指定模板實參,
87.無法定義一個typedef參考OBJ<T>,因為模板不是一個型別,但是C++11可以使用using來為類模板定義一個型別別名,例如template<typename T> using foo = bar<T>;
88.如果使用模板型別引數的型別成員,則必須顯示地用typename關鍵字指示該名字是一個型別,例如typename T::value_type * p;
89.為了避免多個檔案實體化相同模板帶來的額外開銷,我們可以使用實體化宣告和實體化定義,在某個檔案定義一個實體化版本,然后在其他檔案只用宣告即可,
90.顯示實體化一個類模板時,會實體化該類的所有成員,因此我們用來顯示實體化一個類模板的型別,必須能用于模板的所有成員,
91.將實參傳遞給帶模板型別的函式形參時,能夠自動應用的型別轉換只有const轉換和陣列或函式到指標的轉換,
92.尾置回傳型別出現在引數串列之后,所以可以用函式的引數來推導尾置回傳型別,
93.通常不能直接定義一個參考的參考,但是通過型別別名或通過模板引數間接定義是可以的,這時會發生參考折疊,
94.只有右值參考的右值參考會折疊成右值參考,
95.std::move用來生成一個右值,而std::forward則保持原有屬性,用于完美轉發引數,
96.當有多個多載模板對一個呼叫提供同樣好的匹配時,會選擇最特例化的版本,
97.引數包擴展中的模式會獨立運用于包中的每個元素,
98.特例化的本質是實體化一個模板,而非多載它,因此,特例化不影響函式匹配,
99.只能部分特例化類模板,而不能部分特例化函式模板,
100.顯示實體化和特例化的區別在于,特例化可以改變原有邏輯,而顯示實體化只能保持原有邏輯,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/42999.html
標籤:C++
下一篇:資料結構之順序表的實作
