C++ Primer Plus(四)
完整閱讀C++ Primer Plus
系統重新學習C++語言部分,記錄重要但易被忽略的,關鍵但易被遺忘的。
友元、異常和其他
1、拋出異常類時,雖然catch的是一個引用,但是也會產生一次拷貝,因為當拋出異常的函數在棧解退的過程中會會調用異常類的析構函數,異常類將不復存在。
2、如果有一個異常類層次結構,應該這樣排列catch塊:將捕獲位於層次結構最下面的異常類的catch語句放在最前面,將捕獲基類異常的catch語句放在最後面。拋出異常的順序要與catch塊相反。
3、在catch語句中使用基類對象時,將捕獲所有的派生類對象,但派生類特性將被剝去,因此將使用虛方法的基類版本。
4、 將dynamic_cast用於引用時,由於沒有與空指針對應的引用值,因此無法使用特殊的引用值來表示失敗,當請求不正確時,將引發bad_cast的異常。
5、reinterpret_cast運算符並不支援所有的類型轉換,例如,可以將指針類型轉換為足以存儲指針的整數,但不能將指針轉換為更小的整型或浮點型。另一個限制是,不能將函數指針和數據指針互相轉換。
string類和標準模板庫
6、使用new分配記憶體時,可以使用auto_ptr、unique_ptr、shared_ptr、但只有unique_ptr有使用new[]和delete[]的版本。
7、在unique_ptr為右值時,可以將其賦值給shared_ptr,模板shared_ptr包含一個顯式構造函數,可以用於將右值unique_ptr轉換為shared_ptr。
8、對於所有內置的算術運算符、關係運算符和邏輯運算符,STL都提供了等價的函數符(仿函數)。
9、valarray模板類重載了許多運算符,可以直接參与大多數數值運算;slice類可用作數組索引,它接受三個值初始值:起始索引、索引數、跨距。
1 valarry<double> arr(10); 2 arr[slice(1,4,3)] = 10;
slice(1,4,3)創建的對象表示選擇4個索引,這可以將arr的第1、4、7、10個元素都設置為10。
10、迭代器類型
Input iterator(輸入迭代器) | 讀,不能寫;只支援自增運算 |
Output iterator(輸出迭代器) | 寫,不能讀;只支援自增運算 |
Forward iterator(前向迭代器) | 讀和寫;只支援自增運算 |
Bidirectional iterator(雙向迭代器) | 讀和寫;支援自增和自減運算 |
Random access iterator(隨機訪問迭代器) | 讀和寫;支援完整的迭代器算術運算 |
輸入、輸出和文件
11、對於標準錯誤輸出,是沒有緩衝區的。
12、在使用cout時,可以使用成員函數width()設置下一次輸出時的欄位寬度,默認右對齊並以空格填充空白欄位,當欄位寬度不足時,C++不對截斷輸出寬度;使用成員函數fill()用來填充空白欄位;使用成員函數precision()來設置浮點數輸出精度;成員函數setf()與unsetf()提供了更豐富的輸出格式設置方法,但使用標準控制符將更加簡單。
13、對於cin的get()方法和getline()方法來說,如果沒有讀取到任何字元(getline()將換行符視為一個字元),則設置failbit;如果讀取了最大數目的字元,但行中還有其他字元,getline()將設置failbit。
14、cin的peak()方法可以查看輸入流中的下一個字元,gcount()方法可以返回最後一個非格式化抽取方法讀取的字元數,putback()方法可以將字元插入到輸入字元串中。
15、fstream類中的方法seekg()和seekp()分別將輸入指針和輸出指針移到指定的文件位置,事實上,由於fstream類使用緩衝區來存儲中間數據,因此指針指向的是緩衝區中的位置,而不是實際的文件。
16、fstream類中的方法tellg()和tellp()方法分別返回輸入流、輸出流當前指針的位置,對於fstream對象,輸入輸出指針將一前一後地移動,因此它們的返回值相同。但對於使用istream對象來管理輸入流,而使用ostream對象來管理同一個文件的輸出流,則輸入指針和輸出指針將彼此獨立的移動。
17、關於如何生成臨時文件,使用tmpnam()可以生產TMP_NAM個不同的文件名,其中每個文件名包含的字元不超過L_tmpnam個。
18、C++庫還提供了sstream族(包含ostringstream類和istringstream類),它們使用相同的介面提供程式和string對象之間的IO。
探討C++新標準
19、新標準引入的移動語義,用來修飾六個特殊函數的default關鍵字,用來刪除任意成員函數的delete關鍵字,以及使用類似初始化列表的方式在一個構造函數中使用另一個構造函數(被稱為委託構造),以及使用using 類名::函數名,使基類所有的非特殊成員函數對派生類可以用(繼承構造函數),以及顯示聲明重寫(覆蓋)某個虛函數的標識符override,以及禁止派生類覆蓋特定的虛函數標識符final。
20、C++11引入lambda表達的主要目的是能夠將類似於函數的表達式用作接受函數指針或函數符的函數的參數。
21、C++提供了多個包裝器對象,用於給其他編程介面提供更一致或更合適的介面。C++11提供了包括模板bind(替代bind1st和bind2nd)、men_fn(將成員函數作為常規函數傳遞)和reference_wrapper(創建行為像引用但可被複制的對象)以及funtion(以統一的方式處理多種類似於函數的形式,使用模板時可減少可執行程式碼的規模)。
22、正確使用遞歸實現可變參數模板。
23、C++11增加了對並行編程的支援,以及相當多的新增庫等。
附錄
24、C++允許定義指向類成員(包括數據和函數)的指針,這種語法需要使用到成員解除引用運算符(* 、->*)。
25、C++11新增了alignof運算符,它接受一個類型作為參數,返回這個類型的對齊方式;noexcept關鍵字用於指出函數不會引發異常,它也可以用作運算符,判斷表達式是否可能引發異常,不引發返回true。
26、STL提供了豐富的全局函數,包括查詢,排序,複製等一系列演算法。
2020年6月2日,星期二,凌晨2點01分,首次完整讀完這本書,共勉。
學如逆水行舟,不進則退;心似平原放馬,易縱難收。