effective and more effective c++
1、盡量用const和inline而不用#define,在定義常量時用const,定義一些小函數時用inline。定義指針常量時要把指針和常量都定義為const,定義成員常量時要把成員定義為static保證所有的實例隻有這一個常量。
2、盡量用<iostream>而不用<stdio.h>,盡量用new和delete而不用malloc和free,對應的new和delete要采用相同的形式,盡量使用C++風格的注釋。
3、析構函數裏對指針成員調用delete,指針成員再構造裏如果沒有分配就要指向0,delete空指針是安全的。
4、安裝set_new_handler()函數,當內存分配不夠時可以回自動調用這裏傳入的函數,可以使程序自然的退出或者想辦法分配出內存。
5、每一個需要動態分配內存的類都需要有一個拷貝構造函數和一個賦值操作符
6、盡量使用初始化而不要在構造函數裏賦值,因為在構造函數裏複製等於成員函數被賦值了兩次。
7、成員在類中聲明的順序決定了他們被初始化的順序,找個和初始化列表中的順序無關。
8、基類一定要有虛析構函數,因為用即被的指針去刪除派生類的結果是無法知道的。
9、讓讓operator=返回*this的引用,很多程序員回返回void,但這樣會導致無法寫出a=b=c這種鏈式賦值,在operator=中一定要檢查自己給自己賦值的情況。
10、類的設計要完整而小,避免public 接口出現數據成員。
11、盡可能使用const
12、避免對指針和數字進行重載,因為當傳入參數值0時,不知道是一個空指針還是0 ,而程序肯定會認為是數字。
13、如果不想使用隱式生成的函數就要顯式地禁止它,例如有時我們如果禁止賦值就需要將operator =放進private。
14、避免返回內部數據的句柄,也不要返回局部對象的引用
15、盡可能地推遲變量的定義
16、一般來說,實際編程時最初的原則是不要內聯任何函數,除非函數確實很小很簡單,因為一旦編譯器拒絕進行內聯,那麼這些聲明為內聯的外聯函數將帶來反而更大的開銷。
17、降低文件之間依賴度的方法:
隻要有可能,盡量讓頭文件不要依賴於別的文件;如果不可能,就借助於類的聲明,不要include它的定義,隻要生明就可以。
如果可以使用對象的引用和指針,就要避免使用對象本身。定義某個類型的引用和指針隻會涉及到這個類型的聲明。定義此類型的對象則需要類型定義的參與。
18、public繼承代表“是一個”,成員代表“有一個”。
19、決不要重新定義繼承而來的非虛函數,決不要重新定義繼承而來的缺省參數值。
20、私有繼承的含義是指基類的所有成員都是派生的私有成員,私有繼承不是繼承關係,它表示通過……而實現,純粹一種實現技術。
21、盡量使用C++風格的類型轉換:static_cast(常規的類型轉換), const_cast(去掉const), dynamic_cast(基類轉化為子類), 和reinterpret_cast(在函數指針類型之間進行轉換)。
22、避免無用缺省構造函數,如果可以沒有缺省的構造函數,就不需要有。在沒有缺省的構造函數而是用數組type a[10]時會有麻煩,解決方法是:
使用指針數組:type** p=new type*[10];for(int i=0;i<10;i++){type[i]=數值};
使用placement new,也就是先分配空間,再在已分配空間上構造:
void* raw=operator new[](10*sizeof(type)); type*a=static_cast<type*>(raw);
for(int i=0;i<10;i++){
new(&a[i]) type(數值)
}
析構時要用placement delete
for(int i=0;i<10;i++){
a[i].~type();
operator delete[](raw);
}
23、自增和自減的符號重載應該寫成
T& operator++(); // ++ 前綴
const T operator++(int);++ 後綴
24、不要重載“&&”,“||”, 或“,”
25、不同類型的new和delete的意義:new/delete/new[]/delete[]:先扥配空間,然後在這個空間上執行構造函數構造對象
operator new(size)/operatoe delete/operator new[](size)/operator delete[];隻是分配一個raw的空間,並不進行構造實體,返回的是void
new (buffer) type():在內存空間buffer上進行構造一個type實例,它的清理時需要直接顯示調用type的析構函數。
26、使用auto_ptr可以避免資源的泄露,因為這裏把指針裝在了auto_ptr的實體裏,實體沒有時調用析構函數會delete掉這個指針。
27、當你必須支持某些操作而不總需要其結果時,懶惰計算是在這種時候使用的用以提高程序效率的技術。當你必須支持某些操作而其結果幾乎總是被需要或被不止一次地需要時,分期攤還是在這種時候使用的用以提高程序效率的一種技術
28、用a+=b替代a=a+b
29、如果想在同一程序下混合C++與C編程,記住下麵的指導原則:將在兩種語言下都使用的函數申明為extern 'C',隻要可能,用C++寫main()。
30、具有虛擬行為的非成員函數很簡單。你編寫一個虛擬函數來完成工作,然後再寫一個非虛擬函數,它什麼也不做隻是調用這個虛擬函數.
31、在類中的靜態對象實際上總是被構造(和釋放),即使不使用該對象。與此相反,隻有第一次執行函數時,才會建立函數中的靜態對象,所以如果沒有調用函數,就不會建立對象。(不過你得為此付出代價,每次調用函數時都得檢查是否需要建立對象。
32、限製某個類隻能在堆中產生:把這個類的析構函數放在priveate裏,寫一個偽析構函數,這樣就不能不采用new來構造這個實例了(因為沒有析構).
限製某個類隻能在堆上分配,將operator new()放在private中,因為new時都要調用oparator new()。
33、不要返回函數內部用new 初始化的指針的引用
34.包含庫文件的順序要從特殊到一般:本地目錄頭文件-自己的庫文件-第三方庫-標準C++庫文件
35、不允許在頭文件中使用using名字空間
36、注意長的參數表,通常這是可以將眾多參數變為類,注意長的函數,通常這可以分成許多函數或者類。
37、不要讓編譯器為我們產生構造、析構、賦值、拷貝構造函數,如果我們不需要就聲明為私有,我們要完全掌控自己的類的行為
38、.編譯期檢查,有些錯誤在運行時用assert不如在編譯階段就發現它,可以利用這個特性,在編譯階段,大小為0的數組會報錯,所以可以定義一個宏或函數
#define STATIC_CHECK(expr) { char unnamed[(expr) ? 1 : 0]; },然後在程序中需要檢查expr的地方調用。這樣一些簡單的檢查就可以在編譯期間發現
最後更新:2017-04-02 04:00:25