程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> effective c++ 筆記 (31-34)

effective c++ 筆記 (31-34)

編輯:C++入門知識

effective c++ 筆記 (31-34)


 

//#32 確定你的public繼承塑膜出 is-a 關系

{

/*

1>子類is-a父類。

如果以public形式繼承,你便是告訴c++編譯器說,每一個類型為子類的對象同時也是一個父類的對象。

也就是父類表現出更一般化的概念。

2>只要是父類能用到的地方,子類也一定能有用,但是如果什麼地方子類能用,父類就不一定能用了。

3>is-a的困惑點:

1)bird能飛,企鵝是bird,所以也能飛:

這裡首先bird並不是都能飛的,所以這裡應該分類成flybird和notflybird。企鵝就能繼承

notflybird了。

然而有些系統並不會用到企鵝,而且能飛的bird還是很多的,所以可以適當考慮不去區分能不能飛

也就是學會靈活變通。

2)正方形是一個矩形:

矩形調整長度的時候,寬度是不會變的,但是正方形調整長度的時候,寬度要跟著變化。

所以解決辦法是改寫正方形的SetWidth和SetHeight,讓這兩個函數在改動一個時,另一個跟著變。

畢竟正方形是一個特殊的長方形,你要改變我的長,ok,寬度也必須跟著變。

*/

}

 

//#33 避免遮掩繼承而來的名稱

{

// 先看看下面的代碼:

class Base

{

public:

virtual void mf1();

virtual void mf1(int);

virtual void mf3();

virtual void mf3(int);

};

 

class Derived : public base

{

virtual void mf1();//並沒有定義mf1(int),所以基類的mf1(int)就被遮蓋了。

using Base::mf1; //這樣才能讓mf1(int)被看見。

virtual void mf3()

{

Base::mf3(); //!!!!!如果是private繼承!!!!!!!(不是private繼承就不要這麼做),這麼做

//可以故意遮蓋基類的mf3(int),只留下基類的mf3()

}

};

}

 

//#34 區分接口繼承和實現繼承

{

/*

1:子類繼承接口總是有三種情況:

1>只繼承函數接口,不繼承實現:pure virtual函數能實現這樣的功能。

2>繼承接口和缺失實現: impure virtual函數。這時會有可能造成危險情況。因為這個接口沒有要求客戶強制

實現,所以如果在有必要的情況下,客戶卻沒有實現,則會造成錯誤。

解決辦法就是:基類提供一個缺失實現的成員函數,子類繼承接口的時候,如果想要缺省實現,直接調用基類

提供的成員函數就行。這時接口聲明成pure virtual的,子類就必須重新實現,至於要不要缺省情況,就看子類

自己調不調用了。

3>繼承接口和強制性實現(不允許修改),non_virtual函數。聲明為non_virtual意味著基類不想子類重定義這個

接口。

2:錯誤情況:

1>全部實現為non_virtual函數,這一的設計使得子類無法定制自己的情況。而且析構函數必須是virtual的(如

果你想讓這個類作為基類的話)

2>全部實現為virtual,例外:interface classes,除了這個類接口,其他的類不應該把接口全設置為virtual

因為這可能是class設計者缺乏堅定立場的前兆。某些函數就是不該被重定義的!

*/

}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved