国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C++箴言:用成員函數(shù)模板接受兼容類型

2019-11-17 05:20:45
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  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(三層繼續(xù)體系)中能發(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<typename T>
class SmartPtr {
 public: // smart pointers are typically
  eXPlicit SmartPtr(T *realPtr); // initialized by built-in pointers
 ...
};

SmartPtr<Top> pt1 = // convert SmartPtr<Middle> =>
SmartPtr<Middle>(new Middle); // SmartPtr<Top>

SmartPtr<Top> pt2 = // convert SmartPtr<Bottom> =>
SmartPtr<Bottom>(new Bottom); // SmartPtr<Top>

SmartPtr<const Top> pct2 = pt1; // convert SmartPtr<Top> =>
// SmartPtr<const Top>
  在同一個(gè) template(模板)的不同 instantiations(實(shí)例化)之間沒有 inherent relationship(繼續(xù)關(guān)系),所以編譯器認(rèn)為 SmartPtr<Middle> 和 SmartPtr<Top> 是完全不同的 classes,并不比(比方說)vector<float> 和 Widget 的關(guān)系更近。為了得到我們想要的在 SmartPtr classes 之間的轉(zhuǎn)換,我們必須顯式地為它們編程。

  在上面的 smart pointer(智能指針)的示例代碼中,每一個(gè)語(yǔ)句創(chuàng)建一個(gè)新的 smart pointer object(智能指針對(duì)象),所以現(xiàn)在我們就集中于我們?nèi)绾螌?smart pointer constrUCtors(智能指針的構(gòu)造函數(shù)),讓它以我們想要的方式運(yùn)轉(zhuǎn)。一個(gè)要害的事實(shí)是我們無(wú)法寫出我們需要的全部 constructors(構(gòu)造函數(shù))。在上面的 hierarchy(繼續(xù)體系)中,我們能從一個(gè) SmartPtr<Middle> 或一個(gè) SmartPtr<Bottom> 構(gòu)造出一個(gè) SmartPtr<Top>,但是假如將來(lái)這個(gè) hierarchy(繼續(xù)體系)被擴(kuò)充,SmartPtr<Top> objects 還必須能從其它 smart pointer types(智能指針類型)構(gòu)造出來(lái)。例如,假如我們后來(lái)加入

class BelowBottom: public Bottom { ... };
  我們就需要支持從 SmartPtr<BelowBottom> objects 到 SmartPtr<Top> objects 的創(chuàng)建,而且我們當(dāng)然不希望為了做到這一點(diǎn)而必須改變 SmartPtr template。

  大體上,我們需要的 constructors(構(gòu)造函數(shù))的數(shù)量是無(wú)限的。因?yàn)橐粋€(gè) template(模板)能被實(shí)例化而產(chǎn)生無(wú)數(shù)個(gè)函數(shù),所以似乎我們不需要為 SmartPtr 提供一個(gè) constructor function(構(gòu)造函數(shù)函數(shù)),我們需要一個(gè) constructor template(構(gòu)造函數(shù)模板)。這樣的 templates(模板)是 member function templates(成員函數(shù)模板)(經(jīng)常被恰如其分地稱為 member templates(成員模板))——生成一個(gè) class 的 member functions(成員函數(shù))的 templates(模板)的范例:

template<typename T>
class SmartPtr {
 public:
  template<typename U> // member template
  SmartPtr(const SmartPtr<U>& other); // for a "generalized
  ... // copy constructor"
};
  這就是說對(duì)于每一種類型 T 和每一種類型 U,都能從一個(gè) SmartPtr<U> 創(chuàng)建出一個(gè) SmartPtr<T>,因?yàn)?SmartPtr<T> 有一個(gè)取得一個(gè) SmartPtr<U> 參數(shù)的 constructor(構(gòu)造函數(shù))。像這樣的 constructor(構(gòu)造函數(shù))——從一個(gè)類型是同一個(gè) template(模板)的不同實(shí)例化的 object 創(chuàng)建另一個(gè) object 的 constructor(構(gòu)造函數(shù))(例如,從一個(gè) SmartPtr<U> 創(chuàng)建一個(gè) SmartPtr<T>)——有時(shí)被稱為 generalized copy constructors(泛型化拷貝構(gòu)造函數(shù))。

  上面的 generalized copy constructor(泛型化拷貝構(gòu)造函數(shù))沒有被聲明為 explicit(顯式)的。這是故意為之的。built-in pointer types(內(nèi)建指針類型)之間的類型轉(zhuǎn)換(例如,從派生類指針到基類指針)是隱式的和不需要 cast(強(qiáng)制轉(zhuǎn)型)的,所以讓 smart pointers(智能指針)模擬這一行為是合理的。在 templatized constructor(模板化構(gòu)造函數(shù))中省略 explicit 正好做到這一點(diǎn)。

  作為聲明,SmartPtr 的 generalized copy constructor(泛型化拷貝構(gòu)造函數(shù))提供的東西比我們想要的還多。是的,我們需要能夠從一個(gè) SmartPtr<Bottom> 創(chuàng)建一個(gè) SmartPtr<Top>,但是我們不需要能夠從一個(gè) SmartPtr<Top> 創(chuàng)建一個(gè) SmartPtr<Bottom>,這就像顛倒 public inheritance(公有繼續(xù))的含義(參見《C++箴言:確保公開繼續(xù)模擬“is-a”》)。我們也不需要能夠從一個(gè) SmartPtr<double> 創(chuàng)建一個(gè) SmartPtr<int>,因?yàn)檫@和從 int* 到 double* 的 implicit conversion(隱式轉(zhuǎn)換)是不相當(dāng)?shù)摹N覀儽仨氃O(shè)法過濾從這個(gè) member template(成員模板)生成的 member functions(成員函數(shù))的群體。

  假如 SmartPtr 跟隨 auto_ptr 和 tr1::shared_ptr 的腳步,提供一個(gè)返回被這個(gè) smart pointer(智能指針)持有的 built-in pointer(內(nèi)建指針)的拷貝的 get member function(get 成員函數(shù))(參見《C++箴言:在資源治理類中預(yù)備訪問裸資源》),我們可以用 constructor template(構(gòu)造函數(shù)模板)的實(shí)現(xiàn)將轉(zhuǎn)換限定在我們想要的范圍:

template<typename T>
class SmartPtr {
 public:
  template<typename U>
  SmartPtr(const SmartPtr<U>& other) // initialize this held ptr
  : heldPtr(other.get()) { ... } // with other's held ptr

  T* get() const { return heldPtr; }
  ...

 PRivate: // built-in pointer held
  T *heldPtr; // by the SmartPtr
};

  三層交換技術(shù) 交換機(jī)與路由器密碼恢復(fù) 交換機(jī)的選購(gòu) 路由器設(shè)置專題 路由故障處理手冊(cè) 數(shù)字化校園網(wǎng)解決方案   我們通過 member initialization list(成員初始化列表),用 SmartPtr<U> 持有的類型為 U* 的指針初始化 SmartPtr<T> 的類型為 T* 的 data member(數(shù)據(jù)成員)。這只有在“存在一個(gè)從一個(gè) U* 指針到一個(gè) T* 指針的 implicit conversion(隱式轉(zhuǎn)換)”的條件下才能編譯,而這正是我們想要的。最終的效果就是 SmartPtr<T> 現(xiàn)在有一個(gè) generalized copy constructor(泛型化拷貝構(gòu)造函數(shù)),它只有在傳入一個(gè) compatible type(兼容類型)的參數(shù)時(shí)才能編譯。

  member function templates(成員函數(shù)模板)的用途并不限于 constructors(構(gòu)造函數(shù))。它們的另一個(gè)常見的任務(wù)是用于支持 assignment(賦值)。例如,TR1 的 shared_ptr(再次參見《C++箴言:使用對(duì)象治理資源》)支持從所有兼容的 built-in pointers(內(nèi)建指針),tr1::shared_ptrs,auto_ptrs 和 tr1::weak_ptrs構(gòu)造,以及從除 tr1::weak_ptrs 以外所有這些賦值。這里是從 TR1 規(guī)范中摘錄出來(lái)的一段關(guān)于 tr1::shared_ptr 的內(nèi)容,包括它在聲明 template parameters(模板參數(shù))時(shí)使用 class 而不是 typename 的偏好。(就像《C++箴言:理解typename的兩個(gè)含義》中闡述的,在這里的上下文環(huán)境中,它們的含義嚴(yán)格一致。)

template<class T> class shared_ptr {
public:
 template<class Y> // construct from
 explicit shared_ptr(Y * p); // any compatible
 template<class Y> // built-in pointer,
 shared_ptr(shared_ptr<Y> const& r); // shared_ptr,
 template<class Y> // weak_ptr, or
 explicit shared_ptr(weak_ptr<Y> const& r); // auto_ptr
 template<class Y>
 explicit shared_ptr(auto_ptr<Y>& r);
 template<class Y> // assign from
 shared_ptr& Operator=(shared_ptr<Y> const& r); // any compatible
 template<class Y> // shared_ptr or
 shared_ptr& operator=(auto_ptr<Y>& r); // auto_ptr
 ...
};
  除了 generalized copy constructor(泛型化拷貝構(gòu)造函數(shù)),所有這些 constructors(構(gòu)造函數(shù))都是 explicit(顯式)的。這就意味著從 shared_ptr 的一種類型到另一種的 implicit conversion(隱式轉(zhuǎn)換)是被答應(yīng)的,但是從一個(gè) built-in pointer(內(nèi)建指針)或其 smart pointer type(智能指針類型)的 implicit conversion(隱式轉(zhuǎn)換)是不被許可的。(explicit conversion(顯式轉(zhuǎn)換)——例如,經(jīng)由一個(gè) cast(強(qiáng)制轉(zhuǎn)型)——還是可以的。)同樣引起注重的是 auto_ptrs 被傳送給 tr1::shared_ptr 的 constructors(構(gòu)造函數(shù))和 assignment operators(賦值操作符)的方式?jīng)]有被聲明為 const,于此對(duì)照的是 tr1::shared_ptrs 和 tr1::weak_ptrs 的被傳送的方式。這是 auto_ptrs 被復(fù)制時(shí)需要獨(dú)一無(wú)二的被改變的事實(shí)的一個(gè)必然結(jié)果(參見《C++箴言:使用對(duì)象治理資源》)。

  member function templates(成員函數(shù)模板)是一個(gè)極好的東西,但是它們沒有改變這個(gè)語(yǔ)言的基本規(guī)則。《C++箴言:了解C++偷偷加上和調(diào)用了什么》闡述的編譯器可以產(chǎn)生的四個(gè) member functions(成員函數(shù))其中兩個(gè)是 copy constructor(拷貝構(gòu)造函數(shù))和 copy assignment operator(拷貝賦值運(yùn)算符)。tr1::shared_ptr 聲明了一個(gè) generalized copy constructor(泛型化拷貝構(gòu)造函數(shù)),而且很明顯,當(dāng)類型 T 和 Y 相同時(shí),generalized copy constructor(泛型化拷貝構(gòu)造函數(shù))就能被實(shí)例化而成為 "normal" copy constructor(“常規(guī)”拷貝構(gòu)造函數(shù))。那么,當(dāng)一個(gè) tr1::shared_ptr object 從另一個(gè)相同類型的 tr1::shared_ptr object 構(gòu)造時(shí),編譯器是為 tr1::shared_ptr 生成一個(gè) copy constructor(拷貝構(gòu)造函數(shù)),還是實(shí)例化 generalized copy constructor template(泛型化拷貝構(gòu)造函數(shù)模板)?

  就像我說過的,member templates(成員模板)不改變語(yǔ)言規(guī)則,而且規(guī)則規(guī)定假如一個(gè) copy constructor(拷貝構(gòu)造函數(shù))是必需的而你沒有聲明,將為你自動(dòng)生成一個(gè)。在一個(gè) class 中聲明一個(gè) generalized copy constructor(泛型化拷貝構(gòu)造函數(shù))(一個(gè) member template(成員模板))不會(huì)阻止編譯器生成它們自己的 copy constructor(拷貝構(gòu)造函數(shù))(非模板的),所以假如你要全面支配 copy construction(拷貝構(gòu)造),你必須既聲明一個(gè) generalized copy constructor(泛型化拷貝構(gòu)造函數(shù))又聲明一個(gè) "normal" copy constructor(“常規(guī)”拷貝構(gòu)造函數(shù))。這同樣適用于 assignment(賦值)。這是從 tr1::shared_ptr 的定義中摘錄的一段,可以作為例子:


template<class T> class shared_ptr {
 public:
  shared_ptr(shared_ptr const& r); // copy constructor

  template<class Y> // generalized
  shared_ptr(shared_ptr<Y> const& r); // copy constructor

  shared_ptr& operator=(shared_ptr const& r); // copy assignment
 
  template<class Y> // generalized
  shared_ptr& operator=(shared_ptr<Y> const& r); // copy assignment
  ...
};
  Things to Remember

  ·使用 member function templates(成員函數(shù)模板)生成接受所有兼容類型的函數(shù)。

  ·假如你為 generalized copy construction(泛型化拷貝構(gòu)造)或 generalized assignment(泛型化賦值)聲明了 member templates(成員模板),你依然需要聲明 normal copy constructor(常規(guī)拷貝構(gòu)造函數(shù))和 copy assignment operator(拷貝賦值運(yùn)算符)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 雷波县| 衡山县| 雷波县| 西乌珠穆沁旗| 习水县| 沅江市| 湖州市| 铜川市| 托克托县| 夏邑县| 九寨沟县| 玉环县| 黑龙江省| 沈阳市| 彝良县| 扶沟县| 会同县| 霍林郭勒市| 石首市| 喜德县| 特克斯县| 安陆市| 眉山市| 河东区| 保靖县| 贞丰县| 时尚| 微博| 南投县| 时尚| 历史| 河西区| 东阿县| 克山县| 民丰县| 长岛县| 罗江县| 社会| 安多县| 年辖:市辖区| 芦溪县|