日本免费精品_最新日韩一区_亚洲视频一区在线_a在线视频观看_天天射夜夜骑_粉嫩av一区二区三区_欧美中日韩免费视频_综合图区欧美_国内精品美女在线观看_午夜精品久久久久久久男人的天堂

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

Effective C++ 2e Item42

2019-09-10 09:07:13
字體:
供稿:網(wǎng)友

條款42: 明智地使用私有繼承

條款35說明,C++將公有繼承視為 "是一個" 的關(guān)系。它是通過這個例子來證實的:假如某個類層次結(jié)構(gòu)中,Student類從Person類公有繼承,為了使某個函數(shù)成功調(diào)用,編譯器可以在必要時隱式地將Student轉(zhuǎn)換為Person。這個例子很值得再看一遍,只是現(xiàn)在,公有繼承換成了私有繼承:

class Person { ... };

class Student:/t/t      // 這一次我們
 private Person { ... };/t   // 使用私有繼承

void dance(const Person& p);        // 每個人會跳舞

void study(const Student& s);       // 只有學(xué)生才學(xué)習(xí)


Person p;/t/t/t   // p是一個人
Student s;/t/t/t  // s是一個學(xué)生

dance(p);/t/t/t   // 正確, p是一個人

dance(s);/t/t/t   // 錯誤!一個學(xué)生不是一個人

很顯然,私有繼承的含義不是 "是一個",那它的含義是什么呢?

"別忙!" 你說。"在弄清含義之前,讓我們先看看行為。私有繼承有那些行為特征呢?" 那好吧。關(guān)于私有繼承的第一個規(guī)則正如你現(xiàn)在所看到的:和公有繼承相反,如果兩個類之間的繼承關(guān)系為私有,編譯器一般不會將派生類對象(如Student)轉(zhuǎn)換成基類對象(如Person)。這就是上面的代碼中為對象s調(diào)用dance會失敗的原因。第二個規(guī)則是,從私有基類繼承而來的成員都成為了派生類的私有成員,即使它們在基類中是保護或公有成員。行為特征就這些。

這為我們引出了私有繼承的含義:私有繼承意味著 "用...來實現(xiàn)"。如果使類D私有繼承于類B,這樣做是因為你想利用類B中已經(jīng)存在的某些代碼,而不是因為類型B的對象和類型D的對象之間有什么概念上的關(guān)系。因而,私有繼承純粹是一種實現(xiàn)技術(shù)。用條款36引入的術(shù)語來說,私有繼承意味著只是繼承實現(xiàn),接口會被忽略。如果D私有繼承于B,就是說D對象在實現(xiàn)中用到了B對象,僅此而已。私有繼承在軟件 "設(shè)計" 過程中毫無意義,只是在軟件 "實現(xiàn)" 時才有用。

私有繼承意味著 "用...來實現(xiàn)" 這一事實會給程序員帶來一點混淆,因為條款40指出,"分層" 也具有相同的含義。怎么在二者之間進行選擇呢?答案很簡單:盡可能地使用分層,必須時才使用私有繼承。什么時候必須呢?這往往是指有保護成員和/或虛函數(shù)介入的時候 ---- 但這個問題過一會兒再深入討論。

條款41提供了一種方法來寫一個Stack 模板,此模板生成的類保存不同類型的對象。你應(yīng)該熟悉一下那個條款。模板是C++最有用的組成部分之一,但一旦開始經(jīng)常性地使用它,你會發(fā)現(xiàn),如果實例化一個模板一百次,你就可能實例化了那個模板的代碼一百次。例如Stack模板,構(gòu)成Stack<int>成員函數(shù)的代碼和構(gòu)成Stack<double>成員函數(shù)的代碼是完全分開的。有時這是不可避免的,但即使模板函數(shù)實際上可以共享代碼,這種代碼重復(fù)還是可能存在。這種目標(biāo)代碼體積的增加有一個名字:模板導(dǎo)致的 "代碼膨脹"。這不是件好事。

對于某些類,可以采用通用指針來避免它。采用這種方法的類存儲的是指針,而不是對象,實現(xiàn)起來就是:

? 創(chuàng)建一個類,它存儲的是對象的void*指針。
? 創(chuàng)建另外一組類,其唯一目的是用來保證類型安全。這些類都借助第一步中的通用類來完成實際工作。

下面的例子使用了條款41中的非模板Stack類,不同的是這里存儲的是通用指針,而不是對象:

class GenericStack {
public:
 GenericStack();
 ~GenericStack();

 void push(void *object);
 void * pop();

 bool empty() const;

private:
 struct StackNode {
   void *data;/t/t    // 節(jié)點數(shù)據(jù)
   StackNode *next;/t       // 下一節(jié)點

   StackNode(void *newData, StackNode *nextNode)
   : data(newData), next(nextNode) {}
 };

 StackNode *top;/t/t/t  // 棧頂

 GenericStack(const GenericStack& rhs);   // 防止拷貝和
 GenericStack&/t/t/t    // 賦值(參見
   operator=(const GenericStack& rhs);    // 條款27)
};


因為這個類存儲的是指針而不是對象,就有可能出現(xiàn)一個對象被多個堆棧指向的情況(即,被壓入到多個堆棧)。所以極其重要的一點是,pop和類的析構(gòu)函數(shù)銷毀任何StackNode對象時,都不能刪除data指針 ---- 雖然還是得要刪除StackNode對象本身。畢竟,StackNode 對象是在GenericStack類內(nèi)部分配的,所以還是得在類的內(nèi)部釋放。所以,條款41中Stack類的實現(xiàn)幾乎完全滿足the GenericStack的要求。僅有的改變只是用void*來替換T。

僅僅有GenericStack這一個類是沒有什么用處的,但很多人會很容易誤用它。例如,對于一個用來保存int的堆棧,一個用戶會錯誤地將一個指向Cat對象的指針壓入到這個堆棧中,但編譯卻會通過,因為對void*參數(shù)來說,指針就是指針。

為了重新獲得你所習(xí)慣的類型安全,就要為GenericStack創(chuàng)建接口類(interface class),象這樣:

class IntStack {/t/t  // int接口類
public:
 void push(int *intPtr) { s.push(intPtr); }
 int * pop() { return static_cast<int*>(s.pop()); }
 bool empty() const { return s.empty(); }

private:
 GenericStack s;/t/t // 實現(xiàn)
};

class CatStack {/t/t  // cat接口類
public:
 void push(Cat *catPtr) { s.push(catPtr); }
 Cat * pop() { return static_cast<Cat*>(s.pop()); }
 bool empty() const { return s.empty(); }

private:
 GenericStack s;/t/t // 實現(xiàn)
};

正如所看到的,IntStack和CatStack只是適用于特定類型。只有int指針可以被壓入或彈出IntStack,只有Cat指針可以被壓入或彈出CatStack。IntStack和CatStack都通過GenericStack類來實現(xiàn),這種關(guān)系是通過分層(參見條款40)來體現(xiàn)的,IntStack和CatStack將共享GenericStack中真正實現(xiàn)它們行為的函數(shù)代碼。另外,IntStack和CatStack所有成員函數(shù)是(隱式)內(nèi)聯(lián)函數(shù),這意味著使用這些接口類所帶來的開銷幾乎是零。

但如果有些用戶沒認(rèn)識到這一點怎么辦?如果他們錯誤地認(rèn)為使用GenericStack更高效,或者,如果他們魯莽而輕率地認(rèn)為類型安全不重要,那該怎么辦?怎么才能阻止他們繞過IntStack和CatStack而直接使用GenericStack(這會讓他們很容易地犯類型錯誤,而這正是設(shè)計C++所要特別避免的)呢?

沒辦法!沒辦法防止。但,也許應(yīng)該有什么辦法。

在本條款的開始我就提到,要表示類之間 "用...來實現(xiàn)" 的關(guān)系,有一個選擇是通過私有繼承。現(xiàn)在這種情況下,這一技術(shù)就比分層更有優(yōu)勢,因為通過它可以讓你告訴別人:GenericStack使用起來不安全,它只能用來實現(xiàn)其它的類。具體做法是將GenericStack的成員函數(shù)聲明為保護類型:

class GenericStack {
protected:
 GenericStack();
 ~GenericStack();

 void push(void *object);
 void * pop();

 bool empty() const;

private:
 .../t/t/t     // 同上
};

GenericStack s;/t/t   // 錯誤! 構(gòu)造函數(shù)被保護


class IntStack: private GenericStack {
public:
 void push(int *intPtr) { GenericStack::push(intPtr); }
 int * pop() { return static_cast<int*>(GenericStack::pop()); }
 bool empty() const { return GenericStack::empty(); }
};

class CatStack: private GenericStack {
public:
 void push(Cat *catPtr) { GenericStack::push(catPtr); }
 Cat * pop() { return static_cast<Cat*>(GenericStack::pop()); }
 bool empty() const { return GenericStack::empty(); }
};

IntStack is;/t/t     // 正確

CatStack cs;/t/t     // 也正確

和分層的方法一樣,基于私有繼承的實現(xiàn)避免了代碼重復(fù),因為這個類型安全的接口類只包含有對GenericStack函數(shù)的內(nèi)聯(lián)調(diào)用。

在GenericStack類之上構(gòu)筑類型安全的接口是個很花俏的技巧,但需要手工去寫所有那些接口類是件很煩的事。幸運的是,你不必這樣。你可以讓模板來自動生成它們。下面是一個模板,它通過私有繼承來生成類型安全的堆棧接口:

template<class T>
class Stack: private GenericStack {
public:
 void push(T *objectPtr) { GenericStack::push(objectPtr); }
 T * pop() { return static_cast<T*>(GenericStack::pop()); }
 bool empty() const { return GenericStack::empty(); }
};

這是一段令人驚嘆的代碼,雖然你可能一時還沒意識到。因為這是一個模板,編譯器將根據(jù)你的需要自動生成所有的接口類。因為這些類是類型安全的,用戶類型錯誤在編譯期間就能發(fā)現(xiàn)。因為GenericStack的成員函數(shù)是保護類型,并且接口類把GenericStack作為私有基類來使用,用戶將不可能繞過接口類。因為每個接口類成員函數(shù)被(隱式)聲明為inline,使用這些類型安全的類時不會帶來運行開銷;生成的代碼就象用戶直接使用GenericStack來編寫的一樣(假設(shè)編譯器滿足了inline請求 ---- 參見條款33)。因為GenericStack使用了void*指針,操作堆棧的代碼就只需要一份,而不管程序中使用了多少不同類型的堆棧。簡而言之,這個設(shè)計使代碼達到了最高的效率和最高的類型安全。很難做得比這更好。

本書的基本認(rèn)識之一是,C++的各種特性是以非凡的方式相互作用的。這個例子,我希望你能同意,確實是非凡的。

從這個例子中可以發(fā)現(xiàn),如果使用分層,就達不到這樣的效果。只有繼承才能訪問保護成員,只有繼承才使得虛函數(shù)可以重新被定義。(虛函數(shù)的存在會引發(fā)私有繼承的使用,例子參見條款43)因為存在虛函數(shù)和保護成員,有時私有繼承是表達類之間 "用...來實現(xiàn)" 關(guān)系的唯一有效途徑。所以,當(dāng)私有繼承是你可以使用的最合適的實現(xiàn)方法時,就要大膽地使用它。同時,廣泛意義上來說,分層是應(yīng)該優(yōu)先采用的技術(shù),所以只要有可能,就要盡量使用它。

上一篇:確認(rèn)Buffer

下一篇:Foo 的辭源

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

欧美日韩中文字幕在线视频| 日韩精品第一区| 国产视频三级在线观看播放| 欧美日韩国产在线| 中文字幕五月天| www.91香蕉视频| 国产对白在线| 日韩精品在线视频| 亚洲欧洲在线观看av| 91九色在线看| 一区二区三区在线不卡| 国产伦精品免费视频| 91精品国产综合久久香蕉最新版| 日韩影院二区| 日韩精品在线看| 精品午夜av| 国产一级免费| 久久久另类综合| 国产黄在线看| 中文字幕国产视频| 欧美天堂一区二区| 国产一区在线观看视频| 亚洲精品中文字幕乱码三区不卡| 区日韩二区欧美三区| 精品在线一区二区| 中文欧美日韩| 在线日韩中文字幕| 亚洲二区自拍| 亚洲欧洲精品在线| av免费观看网站| 欧美日韩视频在线| 国产激情久久久| 日韩欧美在线看| 国产亚洲污的网站| 91精品免费观看| 久久综合九色欧美综合狠狠| 日韩精品在线视频观看| 国产一级在线免费观看| 在线不卡一区二区| 99国产成 人 综合 亚洲欧美| 中文字幕视频在线免费欧美日韩综合在线看| 日本а中文在线天堂| 亚洲日本精品视频| 日韩不卡在线播放| 91精品久久久久| 日韩精品视频免费在线观看| 欧美久久久精品| 欧美日韩亚洲综合| 亚洲久草视频| 国产亚洲视频中文字幕视频| 日韩欧美国产成人一区二区| 欧美日韩综合在线观看| 日本精品福利视频| 日韩中文字幕91| 亚洲一区二区三区精品中文字幕| 中文字幕第一页在线播放| 在线精品日韩| 欧美在线观看视频一区| 午夜一区二区三区| 日韩欧美综合| 九色蝌蚪视频在线| 日韩欧美亚洲区| www日韩欧美| 影音先锋中文字幕在线观看| 日韩在线视频观看正片免费网站| 国产午夜精品久久| 在线欧美日韩精品| 欧美成人一区二区| 国产嫩草影院久久久久| 日韩视频中文字幕| 日韩三级免费观看| 亚洲电影中文字幕在线观看| 亚洲第一福利视频在线| 精品一二三区| 亚洲第一视频在线观看| 日韩在线播放一区二区| 中文字幕日韩欧美| 欧美日韩综合在线免费观看| 一区在线播放视频| 在线看av的网址| 天天综合天天添夜夜添狠狠添| 日韩福利视频导航| 欧美日韩国产首页| 亚洲福利精品在线| 欧美日韩精品久久久| 精品日本视频| 激情国产在线| 亚洲欧美伊人| 日韩欧美不卡在线| 亚洲精品中文字幕乱码三区不卡| 内射国产内射夫妻免费频道| 欧美大片在线观看一区| 亚洲最新永久观看在线| 久久99久久久久久久噜噜| 日韩欧美在线精品| 亚洲欧美伊人| 99久久精品国产成人一区二区| 欧美二三四区| 欧美日韩色综合| 午夜福利一区二区三区| 视频一区二区国产| 在线三级av| 日韩中文字幕精品视频| 国产三级做爰在线观看| 77777_亚洲午夜久久多人| 老司机久久99久久精品播放免费| 欧美日韩中文国产| 国产福利一区二区| 欧美日韩国产免费观看视频| 91精品国产高清久久久久久| 久久综合九色欧美综合狠狠| 日韩不卡在线播放| 最近中文字幕在线中文视频| 亚洲第一福利视频在线| 99精品电影| 久久久精品国产99久久精品芒果| 国产福利第一页| 亚洲大片精品永久免费| 国产一区激情在线| 91精品国产综合久久精品| 在线看欧美日韩| 欧美日韩精品高清| 一区二区三区四区五区视频在线观看| 中文在线不卡| 国产一区三区三区| 国产香蕉精品视频| 欧美日韩综合高清一区二区 | 国产拍揄自揄精品视频麻豆| 免费看日韩精品| 在线一区二区三区精品| 亚洲图片小说综合| 成片免费观看| 91麻豆精品国产91久久久使用方法| 亚洲欧美99| 日韩欧美在线综合网| 91精品国产91| а√天堂中文在线资源8| 中文字幕日韩欧美在线| 欧美日韩亚洲91| 日韩精品视频在线播放| 高清国产一区| 亚洲视频色图| 狠狠色噜噜狠狠狠狠97| 91精品免费在线观看| 快she精品国产999| 成人精品国产福利| 久久久久久91| 精品视频www| 久久99久久久久久久噜噜| 欧美日韩精品在线观看| 欧美国产一区视频在线观看| 在线中文字幕视频| 精品国产乱码一区二区| 黄色一级大片在线免费看国产一| 精品国产免费视频| 精人妻一区二区三区| 亚洲欧美伊人| 日韩精品综合在线| 久精品在线观看| 中文字幕在线导航| 中文字幕日韩免费视频| 亚洲视频电影在线| 亚洲乱码在线观看| 日韩精品视频在线免费观看| 欧美xxxx中国| 日韩高清不卡| 综合激情国产一区| 日韩国产在线不卡视频| 欧美日韩三级视频| 首页国产欧美久久| 日韩三级精品电影久久久| 国产伦精品免费视频| 国产劲爆久久| 交视频在线观看国产| 国产高清一级片| 日韩中文字幕在线视频播放 | 一本一道综合狠狠老| 欧美日韩国产成人| 日韩亚洲欧美中文字幕| 欧美三级日韩三级| 中文字幕日韩在线视频| 日韩欧美中文视频| 视频一区视频二区中文| 亚洲欧美日本另类| 亚洲中午字幕| 高清在线一区| 久久99久久久久久久噜噜| 久精品在线观看| 日韩视频一区在线观看| av免费看在线| 日韩欧美在线视频| 亚洲高清在线免费| 国产成人精品综合网站| 91久久大香伊蕉在人线| 一区二区三区在线播放视频| 日韩国产在线观看一区| 日韩精品视频在线| 日韩三级视频在线播放| 欧美日韩中文字幕一区| 91精品免费看| 在线综合 亚洲 欧美中文字幕| 日韩精品免费观看视频| 亚洲一区在线观看网站| 综合激情国产一区| 亚洲高清在线免费| 日韩.欧美.亚洲| 欧美三级在线看| 日韩欧美一级视频| 91久久大香伊蕉在人线| 日韩精品a在线观看91| 国产日韩av高清| 成人精品视频一区| 国产不卡在线| 国产欧美中文字幕| 日韩精品视频在线播放| 中文网丁香综合网| 亚洲综合在线中文字幕| 欧美三级网址| 91精品在线免费| 国产福利一区二区| 国产在线一区二区视频| 免费视频久久| 欧美日韩久久久| 欧美xxxx中国| 一级片免费在线播放| 91久久精品视频| 92久久精品| 亚洲一区精品在线| 欧美日韩免费不卡视频一区二区三区| 婷婷中文字幕综合| 日韩视频国产视频| 日韩在线视频二区| 一级片免费网站| 91精品国产综合久久香蕉的特点| 深夜日韩欧美| 日韩午夜高潮| 午夜一区二区三区免费| 人成免费在线视频| 中文字幕第一页在线播放| 中文国产字幕在线观看| 日本亚洲欧美| 日韩三级免费观看| 日韩国产91| 日韩精品视频在线观看视频| 久久蜜桃一区二区| 日韩欧美一二三区| 中文字幕在线视频网| 日本中文字幕在线观看| 亚洲国产91精品在线观看| 成人一区二区不卡免费| 蜜桃精品在线| 欧美日韩国产免费观看视频| 拍真实国产伦偷精品| 亚洲欧美伊人| 亚洲福利在线视频| 欧美日韩精品免费在线观看视频| 国产 日韩 欧美 综合 一区| 欧美日韩高清在线| 精品视频国产| 欧美色欧美亚洲高清在线视频| 日韩精品午夜| 日韩在线观看视频一区| 国产免费久久| 亚洲图片小说综合| 视频一区日韩| 亚洲大片精品永久免费| 精品免费久久久| 久久精品日韩欧美| 国产视频不卡| 中文字幕日韩视频| 欧美日韩高清在线播放| 中文字幕第一页在线播放| 国产黄色一区| 婷婷中文字幕在线观看| 欧美日中文字幕| 午夜亚洲一区| 国产乱码午夜在线视频| 视频一区二区不卡| 日韩欧美国产亚洲| 久久综合久久综合九色| 欧美,日韩,国产在线| 日韩视频 中文字幕| 欧美日韩一区二区在线视频| 国产福利不卡| 日韩免费视频一区| 国产99精品| 欧美久久久精品| 国产中文在线播放| av免费观看网站| 精品激情国产视频| 欧美一级手机免费观看片| 欧美不卡123| 久99久视频| 91精品国产亚洲| 粉嫩喷白浆久久| 亚洲综合欧美在线| 日韩欧美国产片| 你懂的亚洲视频 | 一二三区精品视频| 一级日韩一级欧美| 欧美国产综合在线V| 午夜国产福利一区二区| 中文字幕日韩欧美| 91精品国产自产| 一区免费在线| 欧美日韩高清一区二区| 日韩精品在线视频观看| 日韩欧美国产不卡| 中文字幕亚洲高清| 91精品在线国产| 午夜伊人狠狠久久| 亚洲成在线观看| 本道综合精品| 国产高清一区| 中文字幕 欧美日韩| 国产福利三区| 欧美中文字幕精品| 一区二区三区精品99久久| 欧美日韩三级视频| 国产www在线观看| 免费视频国产一区| 97久久精品午夜一区二区| 粉嫩粉嫩芽的虎白女18在线视频| 免费在线视频一级不卡| 91一区二区| 国产三级第一页| 久久精品国产2020观看福利| 欧美日韩激情一区二区三区| 一本一道综合狠狠老| 中文字幕在线看视频国产欧美| 久久精品日韩无码| 日本熟女一区二区| 中文字幕久久精品| 国产日韩专区| 久久精品一二三| 亚洲区中文字幕| 亚洲欧美久久234| 一区在线播放视频| 日韩欧美国产片| 久久久99免费| 欧美日韩国产一区在线| 国产欧美自拍一区| 精品久久香蕉国产线看观看gif| 欧美日韩激情一区| 亚洲第一视频网站| 欧美日韩亚州综合| 中文字幕第一页在线播放| 999精品视频在线观看播放| 日韩欧美亚洲国产一区| 亚洲二区自拍| 亚洲日产av中文字幕| 日韩精品视频在线观看免费| 国产视频二区| 久久精品免费在线观看| 久久av免费| 久久精品最新免费国产成人| 欧美高清一区| 91欧美日韩| 欧美日韩国产91| 中文字幕伊人| 中文字幕视频在线免费欧美日韩综合在线看 | 77777_亚洲午夜久久多人| 日韩在线视频免费观看| 日韩美女视频一区二区在线观看| 一区免费在线| 国产蜜臀在线| www在线视频| 日韩免费视频| 日韩不卡一二三区| 国产卡1卡2卡三卡在线| 精品在线观看一区| 日韩视频中文字幕| 精品一二三区| 97视频在线| 精品国产欧美| 日韩三级视频在线看| 欧美婷婷久久| 区日韩二区欧美三区| 日韩视频免费直播| 中文字幕第一页在线播放| 亚洲羞羞网站| 在线看欧美日韩| 日韩精品首页| 精品日韩在线观看| 一区二区三区在线|网站| 日韩一级网站| 91精品久久久久久久久久| 欧美性生交大片免费| 999精品网| 久久久91精品国产| 99精品视频99| 美日韩精品免费视频| 一区二区中文视频| 久久精品免费在线观看| 国产成人精品日本亚洲专区61 | 亚洲中文字幕在线一区| 亚洲综合视频一区| 日韩欧美中文在线视频| 九九精品调教| 日韩中文字幕观看|