亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

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

2019-11-17 05:20:45
字體:
來源:轉載
供稿:網友

  smart pointers(智能指針)是行為很像指針但是增加了指針沒有提供的功能的 objects。例如,《C++箴言:使用對象治理資源》闡述了標準 auto_ptr 和 tr1::shared_ptr 是怎樣被應用于在恰當的時間自動刪除的 heap-based resources(基于堆的資源)的。STL containers 內的 iterators(迭代器)幾乎始終是 smart pointers(智能指針);你絕對不能指望用 "++" 將一個 built-in pointer(內建指針)從一個 linked list(線性鏈表)的一個節點移動到下一個,但是 list::iterators 可以做到。

  real pointers(真正的指針)做得很好的一件事是支持 implicit conversions(隱式轉換)。derived class pointers(派生類指針)隱式轉換到 base class pointers(基類指針),pointers to non-const objects(指向非常量對象的指針)轉換到 pointers to const objects(指向常量對象的指針),等等。例如,考慮在一個 three-level hierarchy(三層繼續體系)中能發生的一些轉換:

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(用戶定義智能指針類)中模擬這些轉換是需要技巧的。我們要讓下面的代碼能夠編譯:

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>
  在同一個 template(模板)的不同 instantiations(實例化)之間沒有 inherent relationship(繼續關系),所以編譯器認為 SmartPtr<Middle> 和 SmartPtr<Top> 是完全不同的 classes,并不比(比方說)vector<float> 和 Widget 的關系更近。為了得到我們想要的在 SmartPtr classes 之間的轉換,我們必須顯式地為它們編程。

  在上面的 smart pointer(智能指針)的示例代碼中,每一個語句創建一個新的 smart pointer object(智能指針對象),所以現在我們就集中于我們如何寫 smart pointer constrUCtors(智能指針的構造函數),讓它以我們想要的方式運轉。一個要害的事實是我們無法寫出我們需要的全部 constructors(構造函數)。在上面的 hierarchy(繼續體系)中,我們能從一個 SmartPtr<Middle> 或一個 SmartPtr<Bottom> 構造出一個 SmartPtr<Top>,但是假如將來這個 hierarchy(繼續體系)被擴充,SmartPtr<Top> objects 還必須能從其它 smart pointer types(智能指針類型)構造出來。例如,假如我們后來加入

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

  大體上,我們需要的 constructors(構造函數)的數量是無限的。因為一個 template(模板)能被實例化而產生無數個函數,所以似乎我們不需要為 SmartPtr 提供一個 constructor function(構造函數函數),我們需要一個 constructor template(構造函數模板)。這樣的 templates(模板)是 member function templates(成員函數模板)(經常被恰如其分地稱為 member templates(成員模板))——生成一個 class 的 member functions(成員函數)的 templates(模板)的范例:

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

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

  作為聲明,SmartPtr 的 generalized copy constructor(泛型化拷貝構造函數)提供的東西比我們想要的還多。是的,我們需要能夠從一個 SmartPtr<Bottom> 創建一個 SmartPtr<Top>,但是我們不需要能夠從一個 SmartPtr<Top> 創建一個 SmartPtr<Bottom>,這就像顛倒 public inheritance(公有繼續)的含義(參見《C++箴言:確保公開繼續模擬“is-a”》)。我們也不需要能夠從一個 SmartPtr<double> 創建一個 SmartPtr<int>,因為這和從 int* 到 double* 的 implicit conversion(隱式轉換)是不相當的。我們必須設法過濾從這個 member template(成員模板)生成的 member functions(成員函數)的群體。

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

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
};

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

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

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(泛型化拷貝構造函數),所有這些 constructors(構造函數)都是 explicit(顯式)的。這就意味著從 shared_ptr 的一種類型到另一種的 implicit conversion(隱式轉換)是被答應的,但是從一個 built-in pointer(內建指針)或其 smart pointer type(智能指針類型)的 implicit conversion(隱式轉換)是不被許可的。(explicit conversion(顯式轉換)——例如,經由一個 cast(強制轉型)——還是可以的。)同樣引起注重的是 auto_ptrs 被傳送給 tr1::shared_ptr 的 constructors(構造函數)和 assignment operators(賦值操作符)的方式沒有被聲明為 const,于此對照的是 tr1::shared_ptrs 和 tr1::weak_ptrs 的被傳送的方式。這是 auto_ptrs 被復制時需要獨一無二的被改變的事實的一個必然結果(參見《C++箴言:使用對象治理資源》)。

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

  就像我說過的,member templates(成員模板)不改變語言規則,而且規則規定假如一個 copy constructor(拷貝構造函數)是必需的而你沒有聲明,將為你自動生成一個。在一個 class 中聲明一個 generalized copy constructor(泛型化拷貝構造函數)(一個 member template(成員模板))不會阻止編譯器生成它們自己的 copy constructor(拷貝構造函數)(非模板的),所以假如你要全面支配 copy construction(拷貝構造),你必須既聲明一個 generalized copy constructor(泛型化拷貝構造函數)又聲明一個 "normal" copy constructor(“常規”拷貝構造函數)。這同樣適用于 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(成員函數模板)生成接受所有兼容類型的函數。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91欧美精品午夜性色福利在线| 日韩成人在线播放| 高清一区二区三区四区五区| 欧美做受高潮1| 9.1国产丝袜在线观看| 日韩美女免费线视频| 中文字幕精品一区久久久久| 一个人www欧美| 亚洲精品成人免费| 精品亚洲一区二区三区四区五区| 日韩亚洲第一页| 亚洲国产欧美一区二区丝袜黑人| 亚洲免费av电影| 精品调教chinesegay| 91视频国产精品| 成人欧美一区二区三区在线| 成年人精品视频| 久久天天躁狠狠躁夜夜躁| 97在线看免费观看视频在线观看| 国产视频精品自拍| 亚洲精品日产aⅴ| 国内精品久久久久影院优| 中文字幕在线看视频国产欧美| 91黑丝在线观看| 国产婷婷97碰碰久久人人蜜臀| 久久激情视频免费观看| 久久99国产精品自在自在app| 久久香蕉国产线看观看av| 欧美激情xxxxx| 精品露脸国产偷人在视频| 欧美高清videos高潮hd| 国产一区二区三区视频免费| 日韩精品在线免费观看| 欧美黄色片在线观看| 欧美性生活大片免费观看网址| 国产午夜精品美女视频明星a级| 亚洲国产97在线精品一区| 久久99精品久久久久久噜噜| 97精品欧美一区二区三区| 亚洲精品久久7777777| 亚洲国产成人精品女人久久久| 国产一区二区三区丝袜| 91午夜在线播放| 亚洲香蕉av在线一区二区三区| 亚洲免费电影在线观看| 亚洲国产欧美精品| 91经典在线视频| 日本高清久久天堂| 成人午夜一级二级三级| 国产成人精品免费视频| 欧美大片免费观看在线观看网站推荐| 久久中文精品视频| 欧美日韩视频免费播放| 81精品国产乱码久久久久久| 在线精品高清中文字幕| 亚洲综合在线做性| 欧美高清第一页| 亚洲第一网站免费视频| 国产精品户外野外| 国产美女91呻吟求| 亚洲码在线观看| 国产有码在线一区二区视频| 国产手机视频精品| 欧美国产视频一区二区| 久久中文久久字幕| 久久影视电视剧凤归四时歌| 欧美理论片在线观看| 欧美黄网免费在线观看| 亚洲精品久久久久久久久久久久久| 久久亚洲精品毛片| 91在线播放国产| 欧美国产视频日韩| 中文欧美日本在线资源| 欧美日韩xxx| 高清欧美一区二区三区| 午夜剧场成人观在线视频免费观看| 福利一区福利二区微拍刺激| 91精品国产综合久久男男| 性欧美暴力猛交69hd| 久久视频国产精品免费视频在线| 高清一区二区三区日本久| 91高潮精品免费porn| 神马国产精品影院av| 国产不卡在线观看| 中文日韩在线观看| 色偷偷偷亚洲综合网另类| 国产一区二区丝袜| 美女久久久久久久| 91精品啪aⅴ在线观看国产| 91九色综合久久| 97精品视频在线| 精品二区三区线观看| 日韩视频在线观看免费| 亚洲欧美日韩综合| 日韩欧美高清在线视频| 亚洲国产成人av在线| 久久综合亚洲社区| 亚洲一级免费视频| 久久中文字幕国产| 久久久在线免费观看| www.久久色.com| 亚洲成人精品视频在线观看| 亚洲激情视频在线播放| 欧美午夜精品久久久久久久| 久久久久久久久久国产精品| 亚洲视频在线观看免费| 国产综合福利在线| 少妇精69xxtheporn| 亚洲综合中文字幕在线观看| 欧美一级成年大片在线观看| 欧美激情精品久久久久久免费印度| 91久久精品久久国产性色也91| 97精品视频在线播放| 国产精品久久久久av免费| 欧美大肥婆大肥bbbbb| 96国产粉嫩美女| 亚洲一区二区精品| 欧洲永久精品大片ww免费漫画| 亚洲国产精品99久久| 国产精品偷伦一区二区| 日韩电视剧免费观看网站| 久久亚洲欧美日韩精品专区| 久久精品国产亚洲精品| 久久视频在线播放| 久久精品亚洲精品| 亚洲精品视频网上网址在线观看| 91免费人成网站在线观看18| 亚洲精品免费一区二区三区| 久久亚洲精品国产亚洲老地址| 精品丝袜一区二区三区| 成人精品久久av网站| 成人两性免费视频| 久久精品美女视频网站| 91国内免费在线视频| 亚洲精品影视在线观看| 欧美有码在线观看| 亚洲裸体xxxx| 午夜精品福利视频| 久久视频在线视频| 久久99视频免费| 国产精品毛片a∨一区二区三区|国| 九九精品在线观看| 欧美久久精品一级黑人c片| 亚洲japanese制服美女| 亚洲香蕉伊综合在人在线视看| 国产日韩欧美在线看| 日韩最新中文字幕电影免费看| 亚洲精品一区av在线播放| 久久精品亚洲一区| 亚洲综合精品伊人久久| 欧美日韩在线影院| 有码中文亚洲精品| 亚洲美女免费精品视频在线观看| 亚洲美女中文字幕| 亚洲日韩中文字幕在线播放| 国产精品久久久久久亚洲调教| 日韩极品精品视频免费观看| 91精品国产色综合久久不卡98口| 欧美老少配视频| 国产精品主播视频| 亚洲国产美女久久久久| 亚洲a中文字幕| 欧美国产精品日韩| 亚洲va久久久噜噜噜|