每周都留給自己一些看書的時間。孔子說過 學而不思則惘,思而不學則殆
總結:一點模板的小結
1.多個類型型參的實參必須完全符合
如:compare(short,int)
2.知道什麼叫模板類型型參,什麼叫實參,什麼叫模板非類型型參
3.顯式實參
4.類模板成員函數
5.類模板的靜態成員
6 類非靜態函數指標
class A {
public:
int f( double d ){cout << d << endl; return true;}
};
typedef int ( A::*PFuncOfA )( double d );
PFuncOfA pfunc = &A::f;
7.個建議:
7.1. using的使用
當一個標頭檔要被他人引用的時候,不建議在標頭檔中使用using,特別是“using namespace”,因為使用using後,必然會引出一個“名字汙染”的問題,在被他人引用的標頭檔中,這個汙染可能是會波及到整個工程。
名字空間本身可以影響using的範圍,所以可以把using放在名字空間中,這樣,using的名字只是在這個名字空間中存在;如果using的名字只在某個類中使用,可以使用typedef,那麼完全只在這個類中存在。
最好還是不要使用using,因為這個東西,在很多時候和使用名字空間的初衷是相違背的。當代碼被他人閱讀的時候,可以直接看到名字空間,根據名字空間,可以更好判斷當前類的功能、特點……這其中也說明,名字空間名稱的定義,也是可以好好斟酌斟酌的。
7.2.類成員變數的保護選擇
從結構體到類,最明顯的改進就是添加了“private protected public”3種保護。在C++中,struct應該是要被class淘汰的,除了為了相容。
類成員變數應該都是private,沒有必須這麼說,但通常絕對是合理的。根據物件導向的思想,一個類的成員就是一個類的一個屬性;一個對象的屬性如果發生改變,對象必須能夠知道,並且進行相應的行為、動作;類的屬性可能只是一個簡單變數,也可能是通過幾個屬性合成的,可能今天是簡單的,改天就需要改成複雜的。所以,成員的變數使用setxxxx的方法來更改、用getxxxx的方法來擷取是非常有意義的。
使用get、set後,再調試的時候可以方便跟蹤,可以知道都在什麼地方、什麼時候你的類的屬性被改變了,什麼時候被讀取了。
一些小細節的建議做法:
1.在迴圈stl迭代器 的時候 ++使用 ++ iterator,不要使用iterator ++。
2.在一個函數裡面用“鎖”的時候,並且這個“鎖”會鎖整個函數調用,用定義臨時變數的方式來控制(在臨時變數構造時上鎖、析構的時候解鎖)。
3.當相同的代碼出現的不同的地方的時候,將這些代碼做成一個函數。
4.如果一個stl的容器需要同步,那麼不只是在添加、刪除、修改的時候,在遍曆的時候也需要。
5.拷貝自己或者他人的代碼的時候,一定注意無用的代碼和注釋,並且整個拷貝過來的代碼的作用。
6.當一個類只準備定義一個對象的時候,就把這個類的構造和解構函式定義成私人。
8.實際上程式員在對待其他程式員時候的態度就很好,帶著一種挑剔和學習的態度; 但一旦對待自己的代碼就很難這麼做; 這就是最致命的。程式員也必須對自己的代碼帶著挑剔和學習的態度; 這個基礎是
假設自己的代碼是錯誤的,然後需要做的是怎麼樣證明自己的代碼是正確的。程式員自身可以在程式產生的每個階段做這些工作:仔細的設計(這個時候畫點時間是值得的,必須保證我們對自己的程式有清晰
的輪廓後才能開始動手寫)、編寫代碼時、單元測試(單元測試的重要性就不在贅婿了)、功能測試。
9拋出類類型的異常,而不是指標。棧展開期間,釋放局部對象所用記憶體,運行局部對象解構函式。堆記憶體則不釋放
10.解構函式應該從不拋出異常
11.為捕獲的異常,調用terminate,退出程式
12.catch應該從最低派生到最高派生
13.利用auto_ptr做異常釋放
14.不能將auto_ptr儲存在標準容器中(複製和賦值的關係)
15.虛繼承 :用於多繼承,實現菱形繼承
16.區別指標和引用:前者可以指向空,引用必須總是代表某個對象
17.最好使用C++轉型操作符:static_cast dynamic_cast const_cast reinterpret_cast
18.不要以多態方式處理數組 class bst ; class bstchild : bst ; fn(bst array[]); 當傳入bstchild arr[10] 時編譯器會被誤導假設數組中每一個元素大小是 bst
19.++ -- 前置和後置形式:注意前置返回自增後的結果,而後置則是返回舊值 所以:
int i = 0; cout << (i++) << endl; 列印出0;
20 不要重載&& || 和,操作符
21 operator new delete 只能改變編譯器new分配的記憶體,不能改變調用建構函式的流程
placement new :例如: new (buffer) Widget(WidgetSize)
釋放: ps->~string() ; delete ps;
22.絕對不要以多態方式處理數組 eg:void fnTest(bstr[] arrBst); bstr如果是類繼承關係,函數調用的時候會造成對象大小
23 非必要不要提供預設建構函式(就自己寫一建構函式貝,還能累死人嗎)
24.以傳引用的方式拋異常
try { CT insT; throw insT;}
catch(CT & rCT){} 為啥要拋引用呢,用指標不是更省事,暈,誰保證指標指向的對象啥時候給析構掉 :?為啥不傳值呢? 汗,兩次拷貝構造挺噁心的。再來個多態調用就掛了
25.瞭解虛擬繼承,不就為了避免菱形繼承嗎:eg: b->a,c->a, d public b,c,暈,搞了連個a,用虛擬繼承吧
26.限制某個類產生的對象數量,HOHO,其實一般使用的是單體,怎麼做單體? 建構函式私人化,加一靜態變數負責儲存唯一的單體。其實這樣還不爽,做一單體的模板類,啥類需要用單體,直接引用就ok,Tsingal<***>...
27.智能指標,其實是一挺難搞的問題。std:auto_ptr.用起來挺爽,但一遇到拷貝構造,就發現指標亂飛了,用的時候小心點(不然一個只能指標指向兩個不同對象算怎麼回事)
哎,還是沒很理解,聽說boost庫提供的智能指標很強悍,找時間看看再回來討論這話題吧
28.c++要調用c的函數,怎麼辦? 有辦法,在第一函式宣告的時候加一extern “C"貝,為啥要這樣做呢,只能怪CPP太強呀,支援函數重載,整出的幾個函數都同一名字,這不改下函數命名規則不亂套嗎。還是C老實點(就是指標有時候給人用得挺噁心的)
29.如果你拷貝的對象中引用了某個外部的內容(比如分配在堆上的資料),那麼在拷貝這個對象的時候,讓新舊兩個對象指向同一個外部的內容,就是淺拷貝;如果在拷貝這個對象的時候為新對象製作了外部對象的獨立拷貝,就是深拷貝( 這個一般人都知道)
30.下面是一些模板的使用小結(泛型的東東在stl大量使用,可見有實用的用處)
30.1 多個類型型參的實參必須完全符合 如compare(short,int)
30.2 知道什麼叫模板類型型參,什麼叫實參,什麼叫模板非類型型參
template <typename T, size_t nSize> class TSingal { TSingal (T& insT);} //T為模板類型型參,nSize為非類型型參
30.3.模板特化:這個挺討厭的,經常記不住,今天還非得把它記清楚了,嘿嘿:那到底什麼叫模板特化:
模板特化是這樣一個定義,該定義中一個或多個模板型參的實際類型或實際值是指定的。
特化的形式如下:
關鍵字template 後面接一對空的角括弧(<>);再接模板名和一對角括弧,角括弧指定這個特化定義的模板型參;
函數型參表;函數體
template<>
int compare<const char*>(const char * &v1, const char * &v2)
{
return strcmp(v1, v2);
}
上面到底特化了什麼,就是相比普通的比較模板 一般是 return v1 > v2;(這裡是做了指標地址大小的比較),但自從特化成了strcmp做比較,就是指標指向的內容做比較了。oh yeah,這樣不就爽多了嗎。可以自由組合。
但是有一點限制:特化的聲明必須與對應的模板相匹配。類模板的特化也是一個道理,就不寫了。
31 類非靜態函數指標
class A {
public:
int f( double d ){cout << d << endl; return true;}
};
typedef int ( A::*PFuncOfA )( double d );
PFuncOfA pfunc = &A::f; 這個可以自己寫個例子覺悟下,其實無非就是引用類成員函數指標
32. using的使用 下面兩個是總部一個老大提的意見,可以琢磨下
32.1. using的使用
當一個標頭檔要被他人引用的時候,不建議在標頭檔中使用using,特別是“using namespace”,因為使用using後,必然會引出一個“名字汙染”的問題,在被他人引用的標頭檔中,這個汙染可能是會波及到整個工程。
名字空間本身可以影響using的範圍,所以可以把using放在名字空間中,這樣,using的名字只是在這個名字空間中存在;如果using的名字只在某個類中使用,可以使用typedef,那麼完全只在這個類中存在。
最好還是不要使用using,因為這個東西,在很多時候和使用名字空間的初衷是相違背的。當代碼被他人閱讀的時候,可以直接看到名字空間,根據名字空間,可以更好判斷當前類的功能、特點……這其中也說明,名字空間名稱的定義,也是可以好好斟酌斟酌的。
32.2.類成員變數的保護選擇
從結構體到類,最明顯的改進就是添加了“private protected public”3種保護。在C++中,struct應該是要被class淘汰的,除了為了相容。
類成員變數應該都是private,沒有必須這麼說,但通常絕對是合理的。根據物件導向的思想,一個類的成員就是一個類的一個屬性;一個對象的屬性如果發生改變,對象必須能夠知道,並且進行相應的行為、動作;類的屬性可能只是一個簡單變數,也可能是通過幾個屬性合成的,可能今天是簡單的,改天就需要改成複雜的。所以,成員的變數使用setxxxx的方法來更改、用getxxxx的方法來擷取是非常有意義的。
使用get、set後,再調試的時候可以方便跟蹤,可以知道都在什麼地方、什麼時候你的類的屬性被改變了,什麼時候被讀取了。