C++編程思想第二卷(實用編程技術)摘要
在c++編程思想的第二卷中介紹了很多更深入的c++特性,這是現代C++編程的精髓
模板
1.一般類的聲明和定義都在H和CPP兩種文件中,主要是怕連接時的多重定義,但是對於模板可以放心的將他們都放在H文件中,因為template後麵的東西編譯器不會為其分配空間,知道有一個模板實例告知。如果不適用內斂的方式,在每次定義模板的函數前都要聲明template,而且聲明中的類名後麵要加<參數>
2.可以這樣定義模板類
template<class T,classu…>
template<class T,int size…>
template<class T,int size=100…>//一個默認值
定義函數模板
template<class T,classu…> void f();
template<typename T…> void f();
在使用函數模板時通產個可以省略模板參數(在可以推斷出來的時候)
可以這樣定義成員函數模板:在類的內部,定義一個函數template<class T,classu…> void f();這個甚至可以是構造函數。
3關鍵字typename:表示他限定的那個詞是一個類型(類內的)而不是一個成員:typename Seq<T>::iterator it;如果不加這個關鍵字,那麼編譯器會認為iterator是成員,有語法錯誤,加上後表示這是一個類型,而it是一個變量。同樣template關鍵字也隻能用在模板類中,這個關鍵字表示他後麵出現的那個<為模板參數列表符而不是小於號。
4.模板的特化
全特化:
template <class Window, class Controller>
class Widget
{
... generic implementation ...
};
template <>
class Widget<ModalDialog, MyController>
{
... specialized implementation ...
};
其中 ModalDialog 和 MyController 時定義好的classes,在這裏當你構建Widget<ModalDialog, MyController>實例時,將用下麵的構造函數,而其他的用上麵的,上麵的稱泛化,下麵的叫特化
偏特化:就是部分參數特化,部分泛化
template <class Window> // Window
class Widget<Window, MyController> // MyController
{
... partially specialized implementation ...
};
這裏window是範化的,MyController是特化的,也就是構造一個任意類和MyController的實例時調用這個構造函數
這個構造可以很複雜,泛化的類可以也是一個模板類
template <class ButtonArg>
class Widget<Button<ButtonArg>, MyController>
{
... further specialized implementation ...
};
5.局部類:
也就是定義在函數中的類,這個類不能定義static成員變量,也不能存取non-static的局部變量
void Fun()
{
class Local
{
... member variables ...
... member function definitions ...
};
... code using Local ...
}
函數不能偏特化
異常處理
1.捕獲所有異常使用catch(...)
2重新像更高一級跑出異常要在catch子句中寫一個throw
3、不捕獲異常,如果異常沒有被任意一個層次捕捉到,那麼就睡直接調用程序中的terminate函數,它的默認實現是abort(),這不是一個正常終止程序的方式,全局變量不被析構
可以使用set_terminate來設置自己的terminate函數。
4、標準異常類:exception,他有很多派生類提供各種異常,可以查閱
5異常規格說明:void f();可能跑出各種異常void f() throw(a,b..);理論上隻拋出這些異常;void f()throw();理論上不拋出任何異常;
如果程序拋出了不在描述中的異常,那麼會調用unexpected()函數,默認下這個函數執行terminate函數,可以使用set_unexpected()來重新設置這個函數。
函數對象:
他是實現了重載()的類的一個實例。
在stl的算法中,這個類的實例通常被用來作為判定函數,它並不是函數,但是因為他重載了(),可以調用a(),類似於一個函數,所以叫做函數對象,它比簡單的判定函數的好處在於它是一個類的對象,它裏麵可以存儲更多的信息
在通用算法中,算法有幾元,它的判定函數就必須使用幾元,算法的元是指它傳遞到判定函數中的參數的個數。
STL算法:
1、填充和生成:fill() fill_n() generate()
2、計數:count() count_if()
3、操作序列: copy() copy_backward() reserve()[倒置] reserve_copy()[倒置後複製它出] rotate()【交換位置】rotate_copyright()
next/preve_permutation()[數學上的排列組合] rondom_shuffle()【隨機重排】 partition()[劃分,將滿足某個條件的元素移到開頭]
4、查找和替換: find/findif()[線性查找] adjacent_find()[查找兩個臨近的相等元素] find_first_of()[在第二個序列上查找與第一個序列上某個元素相等的元素]
search()[查找第二個序列是否出現在第一個序列中(次序也一致)] find_end()[同serch,但是返回最後出現的那一段位置]
search_n()[查找一組相鄰的同樣的值] min/max_element()[找到最小/大的那個值首次出現的位置] replace()replace_if()replace_copy_if()[找到後替換]
5、比較範圍:equal()【兩個範圍是否元素相同順序相同】lexicographical_compare()[比較兩個範圍的字典編纂順序]
6、刪除元素:remove() remove_if() remove_copy_if()
unique()[刪除相鄰的同樣的元素(相鄰的值留下一個),通常之前先用sort(),這樣可以每個元素都隻有一個]
7、排序合並:sort()[按升序排序] stable_sort()[按升序排序並保持相等元素的順序] partitial_sort()【部分排序】nth_element()[保證其中一個元素作為劃分點,左側小於它,右側大於他,用
於算中值和百分點] binary_serach()[在已排序的範圍內尋找] upper_bound()[在一個範圍內找出大於一個值的元素最後出現的那個位置]
equal_range()【找到在一個範圍內某隻出現的範圍】merge() inplace_merge()[合並]
在已拍好序的集合上的集合運算
include()【是否包含】set_union/differrence/intersection/symmetric_difference()
8、堆運算:通常可以將一個序列轉化成一種類似於對的結構,在這裏麵便於一次找出優先權最高的元素
make_heap()[將序列轉化成堆]push_heap() pop_heap()[將堆頂的元素一道序列的最尾斷,不是移除]sort_heap()【將一個堆序的序列重新變成一個按順序排列的序列】
9、對一個範圍的成員全部應用某種運算;foreach()【對每個成員使用某個函數】transforma()【對每個成員使用某個函數並把結果寫入一個序列】
10、數值算法:accumulate()【對所有元素循環的調用一個函數得到一個累計的值】inner_product()【內積】partitial_sum()adjacent_diffrence()[得到原數列相鄰元素的差]
11、其他:pair():一個封裝兩個對象的類,通過make_pair()構造
distance():返回兩個迭代器之間的距離,增加次數
back_inserter/inserter/front_inseeter():為一個容器構建一個迭代器,這個迭代器隻用於在某個位置進行插入
min() max() [比較] swap()[值交換]
容器:
容期間可以通過assign進行互相的轉換
vector:它可以快速的訪問,但支不持在中間插入,它溢出時的代價很高,因為先要分配更大的存儲空間,然後把原先的內容拷貝過來。可以使用reserved告知預先要多大的空間,而使一個整數作為它的構造函數的第一個參數的做法則是把所有的成員默認初始化。
使用vector的最有效的方法是,在開始使用reserved告訴預先需要的空間大小,然後隻在序列後端插入或刪除元素
deque:在不確定對象數量時盡量用它而不用vector,因為它在兩端插入或刪除的效率更高。但是隨機訪問不如vector。它不支持中間插入。
list:在任意地方插入刪除,但是不支持隨機訪問,隻能遍曆,遍曆效率也較慢。如果是較大較多的對象,尤其是構造很麻煩的對象,盡量使用它,如果要進行排序等更是的,因為在list中這通常隻需要改變指針的指向而已。
適配器:stack、queue、prioruty_queue為適配器,他們是用vector、list和dequeue來實現的,每一個適配器都可以用它們分別實現。它們的默認方式通常被認為是最好的。
prioruty_queue:出於安全,它沒有設計迭代器,但是可以使用mack_heap等操作講vector模擬成優先隊列。
關聯式容器:set/multyset/map/multymap都是,它們的特點是將一個值關聯一個關鍵字,set可看成隻有關鍵字。
set:存放唯一的且排過序的成員。
表示二進製位:
c中沒有表示二進製數值的方法,隻有十進製和十六進製,有兩個方法可以代替。
bitset類:它表示有固定位數的二進製串。
vector<bool>容器
valarray容器,他可以操縱一組數組,然後進行各種數值運算,可以對其中的一部分切片出來分析。
最後更新:2017-04-02 04:00:25