smart pointers(智能指針)是行為很像指針但是增加了指針沒有提供的功能的 objects。例如,《C++箴言:使用對(duì)象管理資源》闡述了標(biāo)準(zhǔn) auto_ptr 和 tr1::shared_ptr 是怎樣被應(yīng)用于在恰當(dāng)?shù)臅r(shí)間自動(dòng)刪除的 heap-based resources(基于堆的資源)的。STL containers 內(nèi)的 iterators(迭代器)幾乎始終是 smart pointers(智能指針);你絕對(duì)不能指望用 "++" 將一個(gè) built-in pointer(內(nèi)建指針)從一個(gè) linked list(線性鏈表)的一個(gè)節(jié)點(diǎn)移動(dòng)到下一個(gè),但是 list::iterators 可以做到。
real pointers(真正的指針)做得很好的一件事是支持 implicit conversions(隱式轉(zhuǎn)換)。derived class pointers(派生類指針)隱式轉(zhuǎn)換到 base class pointers(基類指針),pointers to non-const objects(指向非常量對(duì)象的指針)轉(zhuǎn)換到 pointers to const objects(指向常量對(duì)象的指針),等等。例如,考慮在一個(gè) three-level hierarchy(三層繼承體系)中能發(fā)生的一些轉(zhuǎn)換: class Top { ... };
class Middle: public Top { ... };
class Bottom: public Middle { ... };
Top *pt1 = new Middle; // convert Middle* => Top*
Top *pt2 = new Bottom; // convert Bottom* => Top*
const Top *pct2 = pt1; // convert Top* => const Top*
在 user-defined smart pointer classes(用戶定義智能指針類)中模仿這些轉(zhuǎn)換是需要技巧的。我們要讓下面的代碼能夠編譯: template
class SmartPtr {
public: // smart pointers are typically
explicit SmartPtr(T *realPtr); // initialized by built-in pointers
...
};
SmartPtr pt1 = // convert SmartPtr =>
SmartPtr (new Middle); // SmartPtr
SmartPtr pt2 = // convert SmartPtr =>
SmartPtr (new Bottom); // SmartPtr
SmartPtr pct2 = pt1; // convert SmartPtr =>
// SmartPtr
在同一個(gè) template(模板)的不同 instantiations(實(shí)例化)之間沒有 inherent relationship(繼承關(guān)系),所以編譯器認(rèn)為 SmartPtr 和 SmartPtr 是完全不同的 classes,并不比(比方說)vector 和 Widget 的關(guān)系更近。為了得到我們想要的在 SmartPtr classes 之間的轉(zhuǎn)換,我們必須顯式地為它們編程。
在上面的 smart pointer(智能指針)的示例代碼中,每一個(gè)語句創(chuàng)建一個(gè)新的 smart pointer object(智能指針對(duì)象),所以現(xiàn)在我們就集中于我們?nèi)绾螌?smart pointer constructors(智能指針的構(gòu)造函數(shù)),讓它以我們想要的方式運(yùn)轉(zhuǎn)。一個(gè)關(guān)鍵的事實(shí)是我們無法寫出我們需要的全部 constructors(構(gòu)造函數(shù))。在上面的 hierarchy(繼承體系)中,我們能從一個(gè) SmartPtr 或一個(gè) SmartPtr 構(gòu)造出一個(gè) SmartPtr ,但是如果將來這個(gè) hierarchy(繼承體系)被擴(kuò)充,SmartPtr objects 還必須能從其它 smart pointer types(智能指針類型)構(gòu)造出來。例如,如果我們后來加入 class BelowBottom: public Bottom { ... };
我們就需要支持從 SmartPtr objects 到 SmartPtr objects 的創(chuàng)建,而且我們當(dāng)然不希望為了做到這一點(diǎn)而必須改變 SmartPtr template。
大體上,我們需要的 constructors(構(gòu)造函數(shù))的數(shù)量是無限的。因?yàn)橐粋€(gè) template(模板)能被實(shí)例化而產(chǎn)生無數(shù)個(gè)函數(shù),所以好像我們不需要為 SmartPtr 提供一個(gè) constructor function(構(gòu)造函數(shù)函數(shù)),我們需要一個(gè) constructor template(構(gòu)造函數(shù)模板)。這樣的 templates(模板)是 member function templates(成員函數(shù)模板)(常常被恰如其分地稱為 member templates(成員模板))——生成一個(gè) class 的 member functions(成員函數(shù))的 templates(模板)的范例: template
class SmartPtr {
public:
template // member template
SmartPtr(const SmartPtr & other); // for a "generalized
... // copy constructor"
};
real pointers(真正的指針)做得很好的一件事是支持 implicit conversions(隱式轉(zhuǎn)換)。derived class pointers(派生類指針)隱式轉(zhuǎn)換到 base class pointers(基類指針),pointers to non-const objects(指向非常量對(duì)象的指針)轉(zhuǎn)換到 pointers to const objects(指向常量對(duì)象的指針),等等。例如,考慮在一個(gè) three-level hierarchy(三層繼承體系)中能發(fā)生的一些轉(zhuǎn)換: class Top { ... };
class Middle: public Top { ... };
class Bottom: public Middle { ... };
Top *pt1 = new Middle; // convert Middle* => Top*
Top *pt2 = new Bottom; // convert Bottom* => Top*
const Top *pct2 = pt1; // convert Top* => const Top*
在 user-defined smart pointer classes(用戶定義智能指針類)中模仿這些轉(zhuǎn)換是需要技巧的。我們要讓下面的代碼能夠編譯: template
class SmartPtr {
public: // smart pointers are typically
explicit SmartPtr(T *realPtr); // initialized by built-in pointers
...
};
SmartPtr pt1 = // convert SmartPtr =>
SmartPtr (new Middle); // SmartPtr
SmartPtr pt2 = // convert SmartPtr =>
SmartPtr (new Bottom); // SmartPtr
SmartPtr pct2 = pt1; // convert SmartPtr =>
// SmartPtr
在同一個(gè) template(模板)的不同 instantiations(實(shí)例化)之間沒有 inherent relationship(繼承關(guān)系),所以編譯器認(rèn)為 SmartPtr 和 SmartPtr 是完全不同的 classes,并不比(比方說)vector 和 Widget 的關(guān)系更近。為了得到我們想要的在 SmartPtr classes 之間的轉(zhuǎn)換,我們必須顯式地為它們編程。
在上面的 smart pointer(智能指針)的示例代碼中,每一個(gè)語句創(chuàng)建一個(gè)新的 smart pointer object(智能指針對(duì)象),所以現(xiàn)在我們就集中于我們?nèi)绾螌?smart pointer constructors(智能指針的構(gòu)造函數(shù)),讓它以我們想要的方式運(yùn)轉(zhuǎn)。一個(gè)關(guān)鍵的事實(shí)是我們無法寫出我們需要的全部 constructors(構(gòu)造函數(shù))。在上面的 hierarchy(繼承體系)中,我們能從一個(gè) SmartPtr 或一個(gè) SmartPtr 構(gòu)造出一個(gè) SmartPtr ,但是如果將來這個(gè) hierarchy(繼承體系)被擴(kuò)充,SmartPtr objects 還必須能從其它 smart pointer types(智能指針類型)構(gòu)造出來。例如,如果我們后來加入 class BelowBottom: public Bottom { ... };
我們就需要支持從 SmartPtr objects 到 SmartPtr objects 的創(chuàng)建,而且我們當(dāng)然不希望為了做到這一點(diǎn)而必須改變 SmartPtr template。
大體上,我們需要的 constructors(構(gòu)造函數(shù))的數(shù)量是無限的。因?yàn)橐粋€(gè) template(模板)能被實(shí)例化而產(chǎn)生無數(shù)個(gè)函數(shù),所以好像我們不需要為 SmartPtr 提供一個(gè) constructor function(構(gòu)造函數(shù)函數(shù)),我們需要一個(gè) constructor template(構(gòu)造函數(shù)模板)。這樣的 templates(模板)是 member function templates(成員函數(shù)模板)(常常被恰如其分地稱為 member templates(成員模板))——生成一個(gè) class 的 member functions(成員函數(shù))的 templates(模板)的范例: template
class SmartPtr {
public:
template // member template
SmartPtr(const SmartPtr & other); // for a "generalized
... // copy constructor"
};