(1)面向?qū)ο缶幊蹋∣OP)與泛型編程(GP)之間的區(qū)別:
OOP試圖將datas與methods關(guān)聯(lián)在一起,為此在OOP中,將數(shù)據(jù)與操作放置在同一個(gè)類中,同時(shí)設(shè)定了類之間的繼承關(guān)系。
GP則是將datas與methods分離。例如sort沒(méi)有被定義為類內(nèi)的成員函數(shù),而是將其歸入STL的算法中,作為一個(gè)全局函數(shù)存在。算法和容器之間利用迭代器進(jìn)行關(guān)聯(lián)。
采用GP編碼:
<1>Containers和Algorithms彼此之間不存在交叉,兩者可以單獨(dú)進(jìn)行開(kāi)發(fā),只需要利用Iterator進(jìn)行溝通即可。
<2>Algorithms可以通過(guò)Iterators確定其操作范圍,并且可以通過(guò)Iterators取用Container中的元素。

在上述例子中,可以看出兩個(gè)max函數(shù)一個(gè)使用了編譯器自帶的<操作,而另一個(gè)使用仿函數(shù)comp自定義比較規(guī)則。對(duì)于所有Algorithms,其中最終涉及元素本身的操作,無(wú)非就是比較大小。由于上述函數(shù)利用了模板,因此應(yīng)當(dāng)注意所傳入的類型T應(yīng)當(dāng)能夠支持進(jìn)行相對(duì)應(yīng)的比較操作,否則則需要對(duì)比較操作運(yùn)算符進(jìn)行重載。
對(duì)于操作符重載應(yīng)該注意:并不是所有的操作符都能夠被重載。重載之后的操作符函數(shù)可以被作為一個(gè)全局函數(shù),也可以被作為一個(gè)成員函數(shù)。
(2)模板
<1>類模板:注意其關(guān)鍵字template<typename T>。其中的T類型不確定,在模板被使用時(shí)確定其具體類型。
<2>函數(shù)模板:其關(guān)鍵字template<class T>。在使用時(shí),編譯器會(huì)對(duì)函數(shù)模板進(jìn)行實(shí)參推導(dǎo),確定模板中T的具體類型。
<3>成員模板
(3)模板的特化
特化可以被分為全特化與偏特化。
<1>一個(gè)被泛化的模板為:
template<class type>
struct A{…..}
經(jīng)過(guò)全特化后為:
template<>struct A<int>{…..}
template<>struct A<double>{…..}
<2>偏特化也被稱為局部特化。
template<class T,class Alloc = alloc>
class vector{......};
實(shí)施偏特化后:
template<class Alloc>
class vector<bool ,Alloc>{......};
上述偏特化為個(gè)數(shù)的偏特化。
template<class ?type>
struct A{…..};
能夠接受任意類型的type。將其進(jìn)行范圍的偏特化,使其只能夠接受固定類型的type。
template<class T>
struct A<T*>{…..};
template<class T>
struct A<const T*>{…..};
(4)分配器allocators
分配器所分配內(nèi)存是使用operator new()和malloc()函數(shù)完成容器所需要的內(nèi)存的分配。

通過(guò)上圖可以看出,通過(guò)分配器所分配的內(nèi)存比實(shí)際所需要的內(nèi)存數(shù)量要大,其中包括cookie等額外所分配的控件。所需要分配的控件越小,則其所額外分配的內(nèi)存在總體內(nèi)存中所占用的比例越大。本周課堂上所比較的幾種編譯器只是以::operator new和::operator delete完成allocate()和deallocate(),沒(méi)有任何特殊的設(shè)計(jì).。
可以利用allocator<int>()完成臨時(shí)對(duì)象的創(chuàng)建。
int* p = allocator<int>().allocate(512,(int*)0);
其中必須指定所分配的內(nèi)存的大小。同時(shí)在進(jìn)行內(nèi)存釋放時(shí):
allocator<int>().deallocate(p,512);
釋放內(nèi)存時(shí)必須同時(shí)給出所分配的內(nèi)存數(shù)目。
在G4.9所附帶的標(biāo)準(zhǔn)庫(kù)中,有許多extention allocators(附加類型的分配器)。
其中__pool_alloc就是G2.9中的alloc。
(5)List
list容器是一種雙向的鏈表,因此其節(jié)點(diǎn)除了存放數(shù)據(jù)之外,還存在一個(gè)向前的指針和一個(gè)向后的指針。
template<class T>
struct __list_node{
? ? typedef void* void_pointer;
? ? void_pointer ? ?prev;
? ?void_pointer ? ? next;
? ?T ?data;
}
由此可知list容器的迭代器的結(jié)構(gòu)如下:
template<class T, class Ref, class Ptr>
struct __list_iterator{
? ? ?typedef ? T ?value_type;
? ? typedef ? Ptr ?pointer;
? ? typedef ?Ref ?reference;
? ? ……
}
除了vector和array之外。其余容器的迭代器都應(yīng)當(dāng)是一個(gè)class,也就是一個(gè)智能指針。
迭代器的++++和----操作:
前++為:
self& operator++()
{
? ? node= (link_type)((*node).next);
? ? return *this;
}
后++為:
self operator++(int)
{
? ? self tmp = *this; ? ? //記錄原值
? ? ++*this; ? ? ? ? ? ? ? ? ?//進(jìn)行操作
? ? return tmp;//返回原值
}
本次編程作業(yè)中要求打印中間元素:
Index = (ListData.size()) / 2;
for(iList = ListData.begin(); iList != ListData.end();++++iList)
{
? ? ? ----Index;
? ? ?if(Index == 0)
? ? ?{
? ? ? ? ? ?cout<< "中間元素為:" << *iList << endl ;
? ? ? ? ? ? break;
? ? ?}
}
使用++++能夠得到正確的節(jié)點(diǎn)值,而++得到的是正確節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)值。
(6)Traits
iterator需要遵循的原則
std::rotate(__first,__middle,__last,std::iterator_category(__first));
在上例中,rotate()需要知道iterators的三個(gè)associated types。
iterators必須有能力回答algorithms的提問(wèn)。這樣的提問(wèn)在C++標(biāo)準(zhǔn)庫(kù)開(kāi)發(fā)過(guò)程中設(shè)計(jì)了五種:category:種類;difference_type;距離;value_type:值類型;reference;pointer。
如果iterator不是一個(gè)class,也就是說(shuō)此時(shí)iterator是一個(gè)原生指針,這時(shí)的iterator被稱為退化的。
Iterator Traits用以分離class?iterators和non—class iterators。


(7)容器vector

Vector容器的容積以二倍增長(zhǎng)的形式增長(zhǎng)。
Vector容器的迭代器就是一個(gè)原生指針。
(8)容器array
Array在C++11后,被添加至容器中。定義一個(gè)array必須指定其長(zhǎng)度,一旦定義,array無(wú)法自動(dòng)變更容積。
(9)forward_list容器
