1.函數參數進棧順序:從右到左
2.字符串化預處理特徵:在表達式前加上‘#’表示將仍和一個表達式轉化成一個字符串。
3.解析一個變量的類型:從中間向外擴展,先右再左,大多數的聲明以左-右左完成(具體結合運算符的優先級來判斷)
eg:
1. void*( * ( *pfun )( int ) )[ 10 ]
解析:pfun是一個函數指針,指向一個參數是int返回值是一個只想有10個void*元素的數組的指針
2.float(* ( *fp2 ) ( int ,int,float ) )( int )
解析:fp2是一個函數指針,指向參數列表是int,int,int返回值是一個函數指針的函數。
(返回值裏的函數指針指向一個返回值是float 參數列表是int)
4.創建函數指針數組,支持“表格驅動碼”概念:可以根據狀態變量選擇函數而不用條件判斷。
eg:
#define DF (N ) void N (){\ cout << "函數"#N"被調用..." << endl ; } DF(a); DF( b); DF(c); DF (d ); DF( e); DF(f); DF (g ); void(*func_table [])() = { a, b , c, d , e, f, g }; int main () { while (1) { cout << "press a key from 'a' to 'g',or 'q'" << endl; char c; cin. get( c); if (c == 'q' ) break; if (c >= 'a' && c <= 'g') (*func_table [c - 'a' ])(); else continue; } return 0; }
5.makefile行爲(p101)
6.任何情況下都不允許同時使用兩個具有同名函數的C庫
7.C++:對象必須要有唯一的標識,對象即變量
8.將函數捆綁在數據結構內部的語言是基於對象而不是面向對象
9.全局作用域解析直接使用::前面不加任何限定
10.嵌套結構的友元:先聲明這個結構->再聲明它是一個友元結構->最後定義
11.句柄類:頭文件放置公共的接口和一個單指針。
所有成員函數的定義一同出現在實現文件中,只要接口部分不變頭文件就不要改動
具體實現的結構被隱藏在實現的文件中。
12.聯合不能作爲基類使用
13.C++的const默認爲是內部連接屬性,所以在定義時必須給他一個值,除非使用extern來說明
14.關鍵字static :不管類被實例化多少次,所有對象都只擁有同一份static實例
15.enum hack:將匿名枚舉嵌套在類中,我們就可以將枚舉裏的數據當成static const
16.const對象:保證該對象的數據成員在其生命期內不被改變
17.const函數:必須保證將const置於參數列表的後面,不修改數據成員的函數都應該把它們聲明爲const
構造和析構都不是const函數,因爲他們總數對數據成員做了一定的修改
18.關鍵字mutable :指定一個特定的數據成員可以再const對象裏面被改變!
19.關鍵字volatile:告訴編譯器:“請不要隨便假設,並且消除冗餘代碼。”
在編輯器認識的範圍外該數據可以被改變!
20.C++的弱類型(模板):一個類型想要調用的成員函數對於一個特定的對象可用
21.return 一個匿名對象和一個非匿名對象是不同的(返回值優化)
eg:
return 類名(數據);
// 這裏編譯器直接把這個對象創建在外部返回值的內存單元
類名 對象名;
return 對象名(數據);
//編譯器首先創建對象,然後將對象拷貝構造給外部返回值的內存單元裏,最後再將tmp析構
22.嵌套的友元類:先聲明類名,再聲明友元,最後定義
23.operator->*:可以直接調用成員函數(p515)
流程:operator->*(函數指針)->返回一個匿名對象
調用operator()
獲得間接引用(真實的)指向成員的指針
*僅用於參數和返回值是int的指針
24.不能重載的運算符:. .*(成員指針的間接引用) ** :: ?:
25.輸入輸出流最好作爲友元原因:運算符>>和<<的左側操作數是ostream的對象和istream的對象,
如果按照正常的思維將其定義出來調用時只能這樣:對象名<<cout;
26.自動類型轉換:當編譯器發現一個表達式或者函數使用了一個不合適的類型,他進行類型轉換
A.構造函數轉換:當編譯器看到類A的方法調用了類B的對象。
而A的構造函數傳參是B類型的,它就會先調用這個構造函數啦
如果你不想這樣的方式發生的話就在構造函數前加上explicit關鍵字
B.運算符轉換:沒有指定返回類型的operator 可以將當前類型轉換成爲希望的類型
eg:
A::operator B() const {return B(_data);}//_data是A類的數據成員
*可以做到從用戶定義類型向內置類型的轉化
27.全局重載運算符可體現反身性,成員版本必須保證左側操作說處於正確的形式!
28.自動類型轉換的缺陷
a.複雜的類型轉換
*編譯器此時認爲這是一個不明指示
b.扇出:在一個類中提供了多種類型的自動轉換函數的重載
c.隱藏的行爲。
29.棧分配運算內置於處理器的指令集裏
30.如果delete一個void 指針則不會調用析構函數(這將是一個程序的錯誤)
*如果程序出現內存丟失的現象記住檢查每一個被delete的指針的類型!
31.容器中含有void*類型的指針,所以他們不能自己管理指針必須由我們負責清除這些對象
*不要講指向棧上內存的指針和指向堆上內存的指針存放在同一個容器裏!
32.儘量將指向數組的指針用const修飾
33.new-handler函數
34.組合:在新類中創建已存在的類的對象
35.構造函數的初始化表達式表:D::D(int data):Bar(data), m(data+1){}
36.組合和繼承的選擇
組合:希望新類具有已存在的類的方法
考慮:你是否需要向上類型轉換
38.漸增式開發:允許在已存在的代碼中引入新代碼,並且新代碼不會導致已存在的代碼發生錯誤
39.向上類型轉換:使用基類指針類型調用子類方法
40.可擴展性:只和基類通信接口
41.派生類如果繼承的是一個抽象類那麼它必須實現基類所有的純虛函數(抽象方法)
42.RTTI:運行時確認
43.對象切片:虛函數使用了傳值調用
44.不把析構函數設置爲虛函數是一個隱匿的錯誤,可能會引入存儲器泄漏