C++学习笔记系列之继承多态
一、移動語義
?
1、右值引用
?
? ? ?有一種機制,可以在語法層面識別出臨時對象,在使用臨時對象構造新對象(拷貝構造)的時候,將臨時對象所持有的資源『轉移』到新的對象中,就能消除這種不必要的拷貝。
?
2、左值和右值
? ? ?左值和右值都是針對表達式而言的, 左值是指表達式結束后依然存在的持久對象
????? 右值是指表達式結束時就不再存在的臨時對象
?????區分: 能對表達式進行取地址,則為左值 否則為右值
?
- 非const左值引用不能綁定到右值上
- const左值引用能綁定到右值上
- const左值引用同時可以綁定到左值上
- 因此,const左值引用作為函數的形參時,無法判斷傳過來的實參是左值還是右值
?
3、右值引用
?
- 右值引用只能綁定到右值上,不能綁定到左值上。
- 移動構造函數,string( string ?&& rhs) ? ?右值引用。
- 常量右值引用沒有現實意義(畢竟右值引用的初衷在于移動語義,而移動就意味著『修改』)。
?
4、移動語義
?
- 問題:臨時對象,帶來的不必要的資源浪費。
- 需求:為了提高程序的執行效率,需要直接將臨時對象的內容直接轉移到新對象之中。
- 問題準換: 需要在語法層面識別出一個臨時對象(右值)?
?
在C++11之前,只有const左值引用能夠綁定到右值,const int & ref = 10 ; 但是它也能綁定到左值,故當const作為函數形參時,實參不能區分是左值還是右值,故提出了----右值引用-->只能綁定到右值,
int && ref = 10 ;
?
String(String && rhs); ? ? //移動構造函數
String & operator=(String && rhs);//移動賦值運算符函數
?
- std : : move函數的作用就是強制將一個左值轉換成右值引用。并且,具有移動語義的函數會優先執行。
- 使用移動語義的特點,該語句之后該對象不會再使用了。
- 編譯器只對右值引用才能調用轉移構造函數和轉移賦值函數,而所有命名對象都只能是左值引用,如果已知一個命名對象不再被使用而想對它調用轉移構造函數和轉移賦值函數。
- 傳遞進來的實參是右值,在函數體內有了名字,就變成了左值。
?
5、資源管理 ---RAII
?
- 利用對象生命周期管理程序資源(包括內存、文件句柄、鎖等)的技術。
- 關鍵:要保證資源的釋放順序與獲取順序嚴格相反
- 在構造時初始化資源, 或托管已構造的資源
- 析構時釋放資源
- 一般不允許復制或賦值(對象語義) - 值語義
- 提供若干訪問資源的方法
?
- RAII的本質是用?棧對象?來管理資源,因為棧對象在離開作用域時,會自動調用析構函數
?
6、資源管理---智能指針 ?RAII(Resource Acquisition Is Initialization) ??資源獲取即初始化時機
?
智能指針(Smart Pointer) ? ?--->利用棧對象來管理資源。
? ? ? ? ? 1、 是存儲指向動態分配(堆)對象指針的類
? ? ? ? ? 2、在面對異常的時候格外有用,因為他們能夠確保正確的銷毀動態分配的對象
?
C++11提供了以下幾種智能指針,位于頭文件<memory>,它們都是類模板
?
- auto_ptr ?被棄用的原因 --> 在語法上來說是可以表達復制語義的,但實現上發生了所有權的轉移,該智能指針存在缺陷。
- std::unique_pt
-
- (獨享型--不能進行復制或賦值 --> 即在它的內里面沒有提供復制構造函數和賦值運算符函數),可以有移動語義。具有移動(std::move)語義(即提供了移動構造函數和移動賦值運算符函數),可做為容器元素 時(需要用移動語義方式添加元素,添加完后,原對象不再被使用),可以指定自定義的刪除器。
- std::shared_ptr? c++11
-
- 共享型,能復制和賦值
- 從語義上來講,可以將對象語義(不能被復制或賦值)準換成值語義(就是能夠被復制和賦值)。
-
- ifstream ifs; ?本身不能復制
- shared_ptr<ifstream> sp(&ifs);
- shared_ptr<ifstream> sp2(sp); //可以復制了。
- shared_ptr是一個引用計數智能指針,用于共享對象的所有權
- 1.引進了一個計數器shared_count,用來表示當前有多少個智能指針對象共享指針指向的內存塊
- 2.析構函數中不是直接釋放指針對應的內存塊,如果shared_count大于0則不釋放內存只是將引用計數減1,只有計數等于0時釋放內存
- 3.復制構造與賦值操作符只是提供一般意義上的復制功能,并且將引用計數加1.
- 問題:循環引用(可能發生內存泄漏)? --->通過weak_ptr 解決
?
? ? ? ? ? ? ??
?
?
- std::weak_ptr? ? c++11
-
- 為了解決循環引用問題而誕生
- std::shared_ptr是強引用智能指針
- std::weak_ptr 是弱引用智能指針
- 強引用,只要有一個引用存在,對象就不能被釋放
- 弱引用,并不增加對象的引用計數,但它只知道對象是否存在。
- 如果存在,提升為shared_ptr成功,提升操作由lock方法完成;否則,提升失敗
- 通過weak_ptr訪問對象的成員的時候,要提升為shared_ptr
- shared_ptr的誤用
?
- 1、同時將一個原生的裸指針交給不同的智能指針進行托管。
-
- Point *pt = new Point(1,2); ? ? std::shared_ptr<Point> p1(pt);//在類之外對對象進行托管 ??
? ? ? ?? std::shared_ptr<Point> p2(pt);
- 2、
-
- shared_ptr<Point> p1(new Point(1, 2)); ??
? ? ?? shared_ptr<Point> p2(new Point(3, 4)); ??
? ? ? ? p2.reset(p1.get());
?
class std::enable_shared_from_this 方法shared_from_this()
?
- g++ -std=c++11 xx.cc
二 、繼承與派生
?
?
1、繼承的概念:
?
? ? ? 在既有類的基礎上定義新的類,而不用將既有類的內容重新書寫一遍,這稱為“繼承”(inheritance),既有類稱為“基類”或“父類”,在它的基礎上建立的類稱為“派生類”或“子類 。
? ? ?
?????MFC已經被微軟棄用。
?????ABC的時代 ? ? ? ? ?A ? ----> ? 人工智能AI
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? B ? ----> ? ?Big ?Data
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? C ? ----> ? ?云的時代
盡量向這些內容上靠。
?
2、繼承的定義形式
? ? ?
? ? ?class 派生類 : 派生方式 基類 {…};? ? //public, protected, private
?????派生類生成過程包含3個步驟:
-
- 吸收基類的成員
- 改造基類的成員
- 添加自己新的成員
?????
3、不能被繼承(繼承的局限性)
? ? ?
-
- 構造函數
- 析構函數
- 用戶重載的new 、delete運算符 ? ? ? ? ? ? ?
-
- operator new /operator delete
- 用戶重載的=運算符 ? ? (對象的復制)
- 友元關系(單向性,不具備傳遞性) ? ?
?
- 繼承時,若不寫關鍵字,默認私有繼承。
- 保護成員不能直接通過對象進行訪問,但是它對其子類、派生類進行開放
- 無論何種繼承,基類的私有成員都不能在派生類內部直接訪問。
- 采用public的繼承方式稱為接口繼承。privated的繼承方式叫實現繼承。protected的繼承稱保護繼承。
- 采用的protected進行繼承時,除了基類的private成員不能在派生類直接訪問外,其他成員都可以在類內部直接訪問。基類public成員在派生類內部變成了protected了
- protected繼承時,除了基類的私有成員在整個繼承體系中不能直接訪問外,其他的非私有成員都可以在派生類內部進行訪問。
- 派生類只有一個基類時,稱為單基派生,在實際運用中,C++同時支持多個基類,這種方法稱為多基派生或多重繼承。
-
- class 派生類名:繼承方式1 基類名1,繼承方式2 基類名2,…,繼承方式n 基類名n { private: ??
-
- 新增私有成員列表;
- public: ??
- 新增公開成員列表;
- };
- 成員名的二義性 ? ----> 作用域限定符 ?::
- 對于存儲二義性,采用虛擬繼承解決, ? ? ? ? ? ? ? ? class C: virtual public A
?
?
? ? ? ? ? ? ? ? ? ?
?
重要基礎: ?---> ?三種繼承方式的訪問權限
?
- 對于派生類創建的對象,只有調用通過pubic繼承的基類的public的成員,其他情況都不能訪問
- 對于基類的私有成員,無論以何種方式進行繼承,在派生類內都不能訪問。
- 對于基類的非私有成員,不論以何種方式繼承,在派生類內部都能直接訪問。
- 如果派生類采用了私有繼承,其基類的非私有成員在這一層級的訪問權限就變成private,之后的派生類均不能再雷內部直接訪問頂層內部的非私有成員,如果才用的protected繼承,在繼承體系之中一直都可以訪問基類的非私有成員。
?
?
4、派生類的構造和銷毀
?
派生類對象的創建總原則: 先完成基類部分的初始化,在完成派生類的初始化。
?
- 派生時,構造函數和析構函數是不能繼承的,構造時,先基類在派生類。
- 系統首先通過派生類的構造函數來調用基類的構造函數,完成基類成員的初始化,而后對派生類中新增的成員進行初始化。
- 如果派生類沒有顯式定義構造函數而基類有,則基類必須擁有默認構造函數。
- 當派生類有顯示定義構造函數時,基類部分的初始化,如果你想調用基類的有參構造函數,必須要在派生類構造函數的初始化列表中顯式調用基類的有參構造函數。
- 調用順序為:
-
- 完成對象所占整塊內存的開辟,由系統在調用構造函數時自動完成。
- 調用基類的構造函數完成基類成員的初始化。
- 若派生類中含對象成員、const成員或引用成員,則必須在初始化表中完成其初始化。
- 派生類構造函數體執行。
- 隱藏機制,當派生類與基類有同名函數時,基類的同名函數會被隱藏,只會執行派生類的同名函數,即使,基類的參數有變化,也會被隱藏。可以通過加上域名限定符,來調用被隱藏的基類成員函數。
?
5、派生類的析構
?
- 當對象被刪除時,派生類的析構函數被執行。析構函數同樣不能繼承。
- 在執行派生類析構函數時,基類析構函數會被自動調用(與虛函數)。
- 執行順序是先執行派生類的析構函數,再執行基類的析構函數,這和執行構造函數時的順序正好相反。
?
6、多基派生類
?
- 各基類構造函數的執行順序與其在初始化表中的順序無關,而是由定義派生類時繼承指定的基類順序決定的。
- 析構函數的執行順序同樣是與構造函數的執行順序相反。
- 覆蓋:
-
- oversee? 隱藏:父子類,函數名稱相同,不帶 ? ? ? ? ? ? ? ? ? virtual關鍵字的函數
-
- 2個函數參數相同,但基類函數不是虛函數。若是虛函數,并且通過對象名去調用的時候,也可以認為是隱藏,通過指針或引用去調用,叫覆蓋。
- 2個函數參數不同,無論基類函數是否是虛函數,基類函數都會被屏蔽。
- override ?覆蓋:父子類,函數的名稱、返回值 ? ? ? ? ? ? ? ? ?類型、參數的類型個數都相同有virtual關鍵字
- overload ?重載:同一個類,函數名稱相同,參 ? ? ? ? ? ? ? ? ? 數不同(類型,順序,個數)
?
7、基類與派生類對象間的相互轉換
?
- 可以把派生類的對象賦值給基類的對象
- 可以把派生類的對象賦值給基類的引用
- 可以聲明基類的指針指向派生類的對象 (向上轉型)
-
- 向下轉型:一般不能進行,只有當sizeof(基類) == sizeof (派生類)
? ??
?????也就是說如果函數的形參是基類對象或者基類對象的引用或者基類對象的指針類型,在進行函數調用時,相應的實參可以是派生類對象 。
?
- 如果用戶定義了基類的拷貝構造函數或者賦值運算符=,而沒有顯式定義派生類的拷貝構造函數,那么在用一個派生類對象初始化新的派生類對象時,兩對象間的派生類部分執行缺省的行為,而兩對象間的基類部分執行用戶定義的基類拷貝構造函數。
- 定義了派生類有顯式定義拷貝構造函數或者重載了派生類的對象賦值運算符=,而基類也有顯式定義,派生類對象初始化新的派生類,或者在派生類對象間賦值時,只會調用派生類的拷貝構造函數或者重載賦值函數,而不會再自動調用基類的拷貝構造函數和基類的重載對象賦值運算符,只有顯式調用基類的拷貝構造或賦值運算符函數。
?
二 、多態
?
?
1、概述
?
? ? ?通常是指對于同一個消息、同一種調用,在不同的場合,不同的情況下,執行不同的行為 。
?
2、分類
?
? ? ?靜態多態性, 和動態多態性。
? ?? 靜態多態性?:函數重載和運算符重載。編譯器可以在編譯過程中完成這種聯編。
? ?? 動態多態性:在程序運行時完成選擇,通過虛函數來實現動態聯編。 ? 繼承 + 虛函數 ?--->實現
?
3、虛函數 ? ---> 通過虛(函數)表 實現
?
- 函數原型前加一個關鍵字virtual即可。當成員函數成為虛函數后,則該對象的存數布局就會多一個虛函數指針,它指向一個虛函數表,表中存放虛函數入口地址。
- 如果一個基類的成員函數定義為虛函數,那么,它在所有派生類中也保持為虛函數;即使在派生類中省略了virtual關鍵字,也仍然是虛函數。
- 虛函數的作用:
-
- 不加virtual時,具體調用哪個版本的disp()只取決于指針本身的類型,和指針所指對象的類型無關。
- 而加virtual時,具體調用哪個版本的disp()不再取決于指針本身的類型,而是取決于指針所指對象的類型。
- 派生類重定義虛函數格式
-
- 與基類的虛函數有相同的參數個數;
- 與基類的虛函數有相同的參數類型;
- 與基類的虛函數有相同的返回類型。
- 虛函數的訪問
-
- 通過對象名調用虛函數,不會展現虛函數的性質,此時虛函數退化成一個普通函數,直接通過函數名去訪問。靜態聯編。
- 使用指針訪問非虛函數時,編譯器根據指針本身的類型決定要調用哪個函數,而不是根據指針指向的對象類型;
- 使用指針訪問? 虛函數時,編譯器根據指針所指對象的類型決定要調用哪個函數(動態聯編),而與指針本身的類型無關。
- 引用訪問類似。
- 在類內的非虛函數成員函數中訪問該類層次中的虛函數,采用動態聯編,要使用this指針。
- 構造函數和析構函數是特殊的成員函數,在其中訪問虛函數時,C++采用靜態聯編。即它們所調用的虛函數是自己類中定義的函數,如果在自己的類中沒有實現該函數,則調用的是基類中的虛函數。但絕不會調用任何在派生類中重定義的虛函數。
?
4、虛函數指針
? ? ? ? ??
- 如果類中包含有虛成員函數,在用該類實例化對象時,對象的第一個成員將是一個指向虛函數表(vftable)的指針(vfptr)。虛函數表記錄運行過程中實際應該調用的虛函數的入口地址。
?
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?
- 動態多態性(虛函數機制)被激活的條件:
-
- 基類要定義一個虛函數
- 派生類要覆蓋該虛函數
- 通過基類的指針或者引用指向派生類對象
- 該指針或引用調用虛函數。
?
- 在構造函數或析構函數之中調用虛函數才用的是靜態聯編。
- 構造函數為什么不能是虛函數?
-
- 答:根據虛函數的使用條件來說,只有先創建對象,在對象創建的過程之中才有了虛函數指針(vfptr),然后才能通過它去調用虛函數。故虛函數的使用時建立在對象的創建,及構造函數之后的。
?
?
5、純虛函數與抽象類
?
- 首先必須是成員函數, 沒有給出實現的函數,用作借口。定義了純虛函數的類成為抽象類,不能實例化。其實現交給派生類實現,若有多個純虛函數,須全部實現,否則,該派生類也是抽象類。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 形式:? ??返回值類型 ?函數名(函數參數) = 0
- 當在基類中無法為虛函數提供任何有實際意義的定義時,可以將該虛函數聲明為純虛函數,它的實現留給該基類的派生類去做。
?
class 類名
{
?????virtual 類型 函數名 (參數表)=0;
????? …
};
?
-
- 純虛函數不能被直接調用創建對象,僅提供一個與派生類一致的接口。
- 一個類可以包含多個純虛函數。只要類中含有一個純虛函數,該類便為抽象類。一個抽象類只能作為基類來派生新類,不能創建抽象類的對象,但可聲明一個指向抽象類的指針。
- 擁有純虛函數的累稱為抽象類
- 使用多態
-
- 繼承 + ?虛函數 ? 實現多態(面向對象的編程)
- bind + function ? 實現多態(基于對象的編程方式) ? --> function/bind 的救贖
- 只定義了protected型構造函數的類也是抽象類,不能直接實例化的類。
- 構造函數不能被定義成虛函數,但析構函數可以定義為虛函數,一般來說,如果類中定義了虛函數,析構函數也應被定義為虛析構函數,尤其是類內有申請的動態內存,需要清理和釋放的時候。
- 一旦基類的虛構函數稱為虛函數之后,派生類的析構函數會自動稱為虛函數。即使沒有給出virtual關鍵字。
?
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?
6、virtual ?繼承 ?(虛擬繼承-虛函數)
?
- 同樣使用 virtual ?關鍵字?---> ?存在、間接和共享 ?這三種特征
- 虛擬繼承如何表現:
-
- 存在即表示虛繼承體系和虛基類確實存在
- 間接性表現在當訪問虛基類的成員時同樣也必須通過某種間接機制來完成(通過虛基表來完成)
- 共享性表現在虛基類會在虛繼承體系中被共享,而不會出現多份拷貝
- 虛繼承:在繼承定義中包含了virtual關鍵字的繼承關系 虛基類:在虛繼承體系中的通過virtual繼承而來的基類
?
語法:
class Subclass : public virtual Baseclass
{
????? public:? ? //...
?????private:? ?//...
????? protected: //...
};
????? 其中Baseclass稱之為Subclass的虛基類; 而不是說Baseclass就是虛基類
?
7、虛擬繼承的一些特性
?
注:以下結論均可通過vs的圖形化調試驗證。
?
- 一:單個虛擬繼承,不帶虛函數? ?
-
- 虛擬繼承與繼承的區別: ? ? ?
-
- 1、虛基類處于對象內存的末尾 ? ? ?
- 2、多了一個虛基指針 (vbptr)
- 二:單個虛擬繼承,帶虛函數 ? ? ?
-
- 如果派生類擁有自己的虛函數(并不是覆蓋),它產生的虛函數指針是位于虛基指針的前面的 。
- 或者說,一個類如果有自己的虛函數,它在內存中的布局一定是位于最開始的位置,原因是為了提高(或者說是派生類的)訪問虛函數的速度 。
- 三:多重繼承(帶虛函數) ??
-
- 1. 每個基類都有自己的虛表 ??
- 2. 派生類的虛成員函數被加入到第一個基類的虛函數表中 ??
- 3. 內存布局中,其基類布局依次按其聲明時的順序進行排列 ??
- 4. 派生類會覆蓋掉基類的對應的虛函數,第一個虛函數表中的被覆蓋的虛函數地址是真實的;之后的虛函數表中的對應的 被覆蓋的虛函數所存放的并不是虛函數的地址,而是一條跳轉指令
- 四:多重繼承具有共同的基類 ?vs? 虛擬繼承 /* 虛基指針所指向的虛基表的內容: ??
-
- 1. 虛基指針的第一條內容表示的是該虛基指針距離所在的子對象的首地址的偏移 ??
- 2. 虛基指針的第二條內容表示的是該虛基指針距離虛基類子對象的首地址的偏移
?
8、虛基派生的構造函數和析構函數
?
- 從虛基類直接或間接派生出來的子類的構造函數初始化列表均有對該虛基類構造函數的調用,這樣就保證虛基類的唯一副本只被初始化一次。即虛基類的構造函數只被執行一次。
- 繼承機制下析構函數的調用順序: 先調用派生類的析構函數,然后調用派生類中成員對象的析構函數 ,再調用普通基類的析構函數 最后調用虛基類的析構函數 。
9、效率
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?
10、擴展閱讀
?
0. 擴展閱讀
http://blog.csdn.net/myan/article/details/5928531
? http://www.cnblogs.com/leoo2sk/archive/2009/04/09/1432103.html
?
1、參考閱讀 ? ? http://blog.csdn.net/haoel/article/details/3081328
?
?http://blog.csdn.net/haoel/article/details/3081385
?
?
三、總結
?
?
1、概述
?
- 客觀世界 ? ? ? ? ? ? ? ? 程序世界
? ? ? ? ? ? ? ? 類到對象? ? ? ? ? ? ? ??實例化
? ? ? ? ? ? ? ? 對象到類 ? ? ? ? ? ? ? ? ?? 抽 ?象
- 對象的管理方式:
-
- 單個對象 ---> 智能指針
- 多個對象 ----> 數據結構 + 算法 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?實現 (STL -->模板)
- OOP (面向對象的編程)
四、面向對象的設計
?
?
1、概述
?
- 面向對象分析(OOA)
- 面向對象編程(OOP)
- 面向對象設計(OOD)
?
經驗:在平常的時候,沒有必要提前告訴他(不然預期太高),可以學其他的東西。在緊急的時候,可以適當表現一下。 ? ? ?--- > ? 以后需要學習的事情。
?
- Unifed Modeling Language(UML), 又稱統一建模語言或標準建模語言,UML為軟件開發提供了一些標準的圖例(10),統一開發思想,從而促進團隊協作 。
?
- 類與類之間的關系
- 繼承(泛化) ?? 垂直的 (A ?is ?B)空心的三角箭頭
- 依賴 ? ?---> 虛線箭頭? 下面四種都是橫向的(水平的) ?A ?use ?B ? ?例子:master 和 pat
- 1. 從語義上來說是 A ? use B,是偶然的,臨時的,并非固定的, 發生在函數調用時。
- 2. B作為A的成員函數參數
- 3. B作為A的成員函數的局部變量
- 4. A的成員函數調用B的靜態方法
?
- 關聯 ? ? ? ? ? 下面三種都是 A ?has ? B ??
- 1.更強的一種關聯關系
- 2. 對象之間的關系表現為分為整體和局部
- 3. 整體部分負責局部對象的銷毀
?
- 組合 ? ?--->實心菱形箭頭
-
- 1、比較強的一種關聯關系
- 2. 對象之間的關系表現為分為整體和局部
- 3. 整體部分并不負責局部對象的銷毀
?
- 聚合 ? --->空心的菱形箭頭
-
- 雙向的關聯關系 ? ? 一條直線
- 單向的關聯關系 ? 一方只知道一方存在 ?->
- 關系是固定的? ?A has B
- 彼此并不負責對方的生命周期
- 一般使用指針或者引用
?
- 總結: ? ----> 很重要的
-
-
- 繼承 ? ? ? ?---> ?繼承關系
- 傳參數 ? ? ---> ?依賴關系
- 指針或引用使用另一個類 ?--> ?關聯關系? (同一層次)
- 整體和局部(指針或引用)? ?---> 聚合關系? ?(不平等的層次上,一個代表整體,一個代表部分)
- 對象成員(強相關) ?---> 組合關系
-
?
- 關系之間的比較
-
- 繼承體現的是類與類之間的縱向關系
- 其他四種體現的是類與類之間的橫向關系
- 耦合強弱: 依賴 < 關聯 < 聚合 < 組合
- 從語義上來看
-
- 繼承(A is B)
- 關聯、聚合、組合(A has B)
- 依賴(A use B)
- 當組合與依賴結合時,可以替代繼承 ? ? ? ??
- 組合+依賴(基于對象) vs? 繼承(面向對象)
?
- 設計原則
-
- 強調模塊間保持低耦合、高內聚的關系 。
- SOLID的5原則
- 單一職責原則(Single Responsibility Principle)
-
- 一個類,最好只做一件事,只有一個引起它變化的原因。原則的核心就是解耦和增強內聚性。
- 開閉原則(Open Closed Principle)
-
- 軟件實體(類,模塊,函數等等)應當對擴展開放,對修改閉合。
- 能在不修改類的前提下擴展一個類的行為。
- 核心思想就是對抽象編程,而不對具體編程,因為抽象相對穩定。
- 里氏替換原則(Liscov Substitution Principle)
-
- 子類必須能夠替換其基類。
- 主要著眼于抽象和多態建立在繼承的基礎上
- 接口分離原則(Interface Segregation Principle)
-
- 接口應該是內聚的,應該避免“胖”接口
- 依賴倒置原則(Dependency Inversion Principle)
-
- 面向接口編程,依賴于抽象
- a.高層模塊不依賴于底層模塊,二者都同依賴于抽象;
- b.抽象不依賴于具體,具體依賴于抽象。
?
- web服務器:
-
- CS : ?qq ? 360殺毒軟件
- BS : ? WIndows: ?IIS ?asp(小型)
-
-
- Apachae(html/php) ? Nginx(html/php) ?(中小型) ? ? ? ? ? ?
- Tomcat/WebLogic(jsp) ?(大型)?
- hadoop ?spark ?( 大數據 )
- Linux內核
-
總結
以上是生活随笔為你收集整理的C++学习笔记系列之继承多态的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第 3 章 镜像 - 015 - 调试
- 下一篇: 非对称加密, 助记词, PIN, WIF