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

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

C++箴言:謹慎使用私有繼承

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

  在《C++箴言:確保公開繼續模擬“is-a”》一文中論述了 C++ 將 public inheritance(公有繼續)視為一個 is-a 關系。
當給定一個 hierarchy(繼續體系),其中有一個 class Student 從一個 class Person 公有繼續,當為一個函數調用的成功而有必要時,需要將 Students 隱式轉型為 Persons,它通過向編譯器展示來做到這一點。用 PRivate inheritance(私有繼續)代替 public inheritance(公有繼續)把這個例子的一部分重做一下是值得的:

  class Person { ... };
  class Student: private Person { ... }; // inheritance is now private

  void eat(const Person p); // anyone can eat

  void study(const Student s); // only students study

  Person p; // p is a Person
  Student s; // s is a Student

  eat(p); // fine, p is a Person

  eat(s); // error! a Student isn't a Person

  很明顯,private inheritance(私有繼續)不意味著 is-a。那么它意味著什么呢?

  “喂!”你說:“在我們得到它的含義之前,我們先看看它的行為。private inheritance(私有繼續)有怎樣的行為呢?”好吧,支配 private inheritance(私有繼續)的第一個規則你只能從動作中看到:與 public inheritance(公有繼續)對照,假如 classes(類)之間的 inheritance relationship(繼續關系)是 private(私有)的,編譯器通常不會將一個 derived class object(派生類對象)(諸如 Student)轉型為一個 base class object(基類對象)(諸如 Person)。這就是為什么為 object(對象)s 調用 eat 會失敗。第二個規則是從一個 private base class(私有基類)繼續的 members(成員)會成為 derived class(派生類)的 private members(私有成員),即使它們在 base class(基類)中是 protected(保護)的或 public(公有)的。

  行為不過如此。這就給我們帶來了含義。private inheritance(私有繼續)意味著 is-implemented-in-terms-of(是根據……實現的)。假如你使 class(類)D 從 class(類)B 私有繼續,你這樣做是因為你對于利用在 class(類)B 中才可用的某些特性感愛好,而不是因為在 types(類型)B 和 types(類型)D 的 objects(對象)之間有什么概念上的關系。同樣地,private inheritance(私有繼續)純粹是一種實現技術。(這也就是為什么你從一個 private base class(私有基類)繼續的每一件東西都在你的 class(類)中變成 private(私有)的原因:它全部都是實現的細節。)利用《接口繼續和實現繼續》中提出的條款,private inheritance(私有繼續)意味著只有 implementation(實現)應該被繼續;interface(接口)應該被忽略。

  假如 D 從 B 私有繼續,它就意味著 D objects are implemented in terms of B objects(D 對象是根據 B 對象實現的),沒有更多了。private inheritance(私有繼續)在 software design(軟件設計)期間沒有任何意義,只在 software implementation(軟件實現)期間才有。 private inheritance(私有繼續)意味著 is-implemented-in-terms-of(是根據……實現的)的事實有一點混亂,正如《通過composition模擬“has-a”》一文中所指出的 composition(復合)也有同樣的含義。你怎么預先在它們之間做出選擇呢?答案很簡單:只要你能就用 composition(復合),只有在絕對必要的時候才用 private inheritance(私有繼續)。什么時候是絕對必要呢?主要是當 protected members(保護成員)和/或 virtual functions(虛擬函數)摻和進來的時候,另外還有一種與空間相關的極端情況會使天平向 private inheritance(私有繼續)傾斜。我們稍后再來操心這種極端情況。

  究竟,它只是一種極端情況。 假設我們工作在一個包含 Widgets 的應用程序上,而且我們認為我們需要更好地理解 Widgets 是怎樣被使用的。例如,我們不僅要知道 Widget member functions(成員函數)被調用的頻度,還要知道 call ratios(調用率)隨著時間的流逝如何變化。帶有清楚的執行階段的程序在不同的執行階段可以有不同的行為側重。
例如,一個編譯器在解析階段對函數的使用與優化和代碼生成階段就有很大的不同。

  我們決定修改 Widget class 以持續跟蹤每一個 member function(成員函數)被調用了多少次。在運行時,我們可以周期性地檢查這一信息,與每一個 Widget 的這個值相伴的可能還有我們覺得有用的其它數據。為了進行這項工作,我們需要設立某種類型的 timer(計時器),以便在到達收集用法統計的時間時我們可以知道。

  盡可能復用已有代碼,而不是寫新的代碼,我在我的工具包中翻箱倒柜,而且滿足地找到下面這個 class(類):

  class Timer {
  public:
  eXPlicit Timer(int tickFrequency);
  virtual void onTick() const; // automatically called for each tick
  ...
  };

  這正是我們要找的:一個我們能夠根據我們的需要設定 tick 頻率的 Timer object,而在每次 tick 時,它調用一個 virtual function(虛擬函數)。我們可以重定義這個 virtual function(虛擬函數)以便讓它檢查 Widget 所在的當前狀態。很完美!

  在《C++箴言:確保公開繼續模擬“is-a”》一文中論述了 C++ 將 public inheritance(公有繼續)視為一個 is-a 關系。當給定一個 hierarchy(繼續體系),其中有一個 class Student 從一個 class Person 公有繼續,當為一個函數調用的成功而有必要時,需要將 Students 隱式轉型為 Persons,它通過向編譯器展示來做到這一點。用 private inheritance(私有繼續)代替 public inheritance(公有繼續)把這個例子的一部分重做一下是值得的:

  class Person { ... };
  class Student: private Person { ... }; // inheritance is now private

  void eat(const Person p); // anyone can eat

  void study(const Student s); // only students study

  Person p; // p is a Person
  Student s; // s is a Student

  eat(p); // fine, p is a Person

  eat(s); // error! a Student isn't a Person

  很明顯,private inheritance(私有繼續)不意味著 is-a。那么它意味著什么呢?

  “喂!”你說:“在我們得到它的含義之前,我們先看看它的行為。private inheritance(私有繼續)有怎樣的行為呢?”好吧,支配 private inheritance(私有繼續)的第一個規則你只能從動作中看到:與 public inheritance(公有繼續)對照,假如 classes(類)之間的 inheritance relationship(繼續關系)是 private(私有)的,編譯器通常不會將一個 derived class object(派生類對象)(諸如 Student)轉型為一個 base class object(基類對象)(諸如 Person)。這就是為什么為 object(對象)s 調用 eat 會失敗。第二個規則是從一個 private base class(私有基類)繼續的 members(成員)會成為 derived class(派生類)的 private members(私有成員),即使它們在 base class(基類)中是 protected(保護)的或 public(公有)的。

  行為不過如此。這就給我們帶來了含義。private inheritance(私有繼續)意味著 is-implemented-in-terms-of(是根據……實現的)。假如你使 class(類)D 從 class(類)B 私有繼續,你這樣做是因為你對于利用在 class(類)B 中才可用的某些特性感愛好,而不是因為在 types(類型)B 和 types(類型)D 的 objects(對象)之間有什么概念上的關系。同樣地,private inheritance(私有繼續)純粹是一種實現技術。(這也就是為什么你從一個 private base class(私有基類)繼續的每一件東西都在你的 class(類)中變成 private(私有)的原因:它全部都是實現的細節。)利用《接口繼續和實現繼續》中提出的條款,private inheritance(私有繼續)意味著只有 implementation(實現)應該被繼續;interface(接口)應該被忽略。

  假如 D 從 B 私有繼續,它就意味著 D objects are implemented in terms of B objects(D 對象是根據 B 對象實現的),沒有更多了。private inheritance(私有繼續)在 software design(軟件設計)期間沒有任何意義,只在 software implementation(軟件實現)期間才有。 private inheritance(私有繼續)意味著 is-implemented-in-terms-of(是根據……實現的)的事實有一點混亂,正如《通過composition模擬“has-a”》一文中所指出的 composition(復合)也有同樣的含義。你怎么預先在它們之間做出選擇呢?答案很簡單:只要你能就用 composition(復合),只有在絕對必要的時候才用 private inheritance(私有繼續)。什么時候是絕對必要呢?主要是當 protected members(保護成員)和/或 virtual functions(虛擬函數)摻和進來的時候,另外還有一種與空間相關的極端情況會使天平向 private inheritance(私有繼續)傾斜。我們稍后再來操心這種極端情況。

  究竟,它只是一種極端情況。
假設我們工作在一個包含 Widgets 的應用程序上,而且我們認為我們需要更好地理解 Widgets 是怎樣被使用的。例如,我們不僅要知道 Widget member functions(成員函數)被調用的頻度,還要知道 call ratios(調用率)隨著時間的流逝如何變化。帶有清楚的執行階段的程序在不同的執行階段可以有不同的行為側重。例如,一個編譯器在解析階段對函數的使用與優化和代碼生成階段就有很大的不同。

  我們決定修改 Widget class 以持續跟蹤每一個 member function(成員函數)被調用了多少次。在運行時,我們可以周期性地檢查這一信息,與每一個 Widget 的這個值相伴的可能還有我們覺得有用的其它數據。為了進行這項工作,我們需要設立某種類型的 timer(計時器),以便在到達收集用法統計的時間時我們可以知道。

  盡可能復用已有代碼,而不是寫新的代碼,我在我的工具包中翻箱倒柜,而且滿足地找到下面這個 class(類):

  class Timer {
  public:
  explicit Timer(int tickFrequency);
  virtual void onTick() const; // automatically called for each tick
  ...
  };

  這正是我們要找的:一個我們能夠根據我們的需要設定 tick 頻率的 Timer object,而在每次 tick 時,它調用一個 virtual function(虛擬函數)。我們可以重定義這個 virtual function(虛擬函數)以便讓它檢查 Widget 所在的當前狀態。很完美!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 体育| 从化市| 汝南县| 忻州市| 青海省| 新兴县| 花垣县| 乐东| 台东县| 沙坪坝区| 建宁县| 岑巩县| 二手房| 古浪县| 澄迈县| 耒阳市| 新化县| 静乐县| 云安县| 北京市| 佛山市| 庆城县| 车致| 武强县| 灵山县| 咸丰县| 阿勒泰市| 剑川县| 安龙县| 英吉沙县| 凌海市| 漳平市| 全椒县| 获嘉县| 松溪县| 石棉县| 泗阳县| 泾川县| 当雄县| 久治县| 汽车|