Object Oriented Programming(OOP)
類(lèi)與類(lèi)的關(guān)系
- Inheritance(繼承)
- Composition(復(fù)合)
- Delegation(委托)
1. Composition(復(fù)合)动分,表示 has-a
Adapter
容器 A 包含實(shí)現(xiàn)多種功能的類(lèi) B, A 可選擇性包含部分 B 中需要的部分
- Composition
// queue 'has-a' deque template <class T> class queue{ .... protected: deque<T> c; //底層容器 public: // 以下完全利用 c 的操作函數(shù)完成 bool empty() const { retrun c.empty;} size_type size() const { return c.size(); } .... } void push(const value_type& x) { c.push_back(x); } void pop() { c.pop_front(); }
大小計(jì)算
復(fù)合類(lèi)的大小由復(fù)合的類(lèi)的大小決定,計(jì)算式逐個(gè)相加
-
// Sizeof: 40 template<clss T> class queue { protected: deque<T> c; ... };
// Sizeof: 16 * 2 + 4 + 4 template <class T> class deque { protected: Itr<T> start; Itr<T> finish; T** map; unsigned int map_size; };
// Sizeof: 4 * 4 template <class T> struct Itr{ T* cur; T* first; T* last; T* node; .... };
構(gòu)造和析構(gòu)
-
構(gòu)造由內(nèi)而外
由內(nèi)而外基礎(chǔ)才穩(wěn)定鳍悠,要做一個(gè)東西袁余,要先弄地基// Container 的構(gòu)造函數(shù)首先調(diào)用 Component 的 default 構(gòu)造函數(shù)脉让,然后才執(zhí)行自己 // "Component()"由編譯器 Container::Container(...): Component() {}; // 如果 default 的構(gòu)造函數(shù)不滿(mǎn)足要求,需要手動(dòng)寫(xiě)明需要調(diào)用的構(gòu)造函數(shù) Container::Container(...): Component(...) {};
-
析構(gòu)由外而內(nèi)
想象在拆掉一個(gè)東西的時(shí)候需要由外而內(nèi)一層層的拆// Container 的析構(gòu)函數(shù)首先執(zhí)行自己,然后才調(diào)用 Component 的析構(gòu)// // "~Component()"由編譯器添加 Container::~Container(...): {.... ~Component() };
2. Delegation(委托),Composition By Reference
Handle / Body
容器 A 中只包含指向功能 B 的指針,需要使用時(shí)才實(shí)例化 B 對(duì)象(可在任何時(shí)候?qū)⑷蝿?wù)“委托”)壶栋。“編譯防火墻”普监,需要修改時(shí)修改 B 即可贵试。
class StringRep; class String { public: String(); ... private: StringRep* rep; //pimpl (point to implementation) }
- Delegation
-
Reference Counting(共享技術(shù))
Reference Counting
3. Inheritance(繼承),表示 is-a
struct _List_node_base{ _List_node_base* _M_next; _List_node_base* _M_prev; }; template<typename _Tp> struct _List_node: public _List_node_base { _Tp _M_data; }
構(gòu)造和析構(gòu)
- Inheritance
-
構(gòu)造由內(nèi)而外
- Derived 的構(gòu)造函數(shù)首先調(diào)用 Base 的 default 構(gòu)造函數(shù)凯正,然后才執(zhí)行自己毙玻。
Derived::Derived(...): Base() { ... };
-
析構(gòu)由外而內(nèi)
- Derived 的析構(gòu)函數(shù)首先執(zhí)行自己,然后才調(diào)用 Base 的析構(gòu)函數(shù)廊散。
Derived::~Derived(...): { ... ~Base(); };
- Base 的析構(gòu)函數(shù)一定要是 virtual 的桑滩,否則會(huì)出現(xiàn) undefined behavior
- (擴(kuò)展)用基類(lèi)指針去操作子類(lèi)對(duì)象時(shí),若基類(lèi)的析構(gòu)函數(shù)不是虛函數(shù)允睹,則在施放內(nèi)存時(shí)只會(huì)調(diào)用基類(lèi)的析構(gòu)函數(shù)运准,造成內(nèi)存泄漏。
Inheritance With Virtual Function
-
class Shape { public: virtual void draw() const = 0; // pure virtual virtual void error(const std::string& msg); // impure virtual int objectID() const; // non-virtual ... }
- pure virtual 函數(shù): 你希望 derived class 一定要重新定義它缭受,你對(duì)它沒(méi)有默認(rèn)定義胁澳。
- virtual 函數(shù):你希望 derived class 重新定義它,且你對(duì)它已有默認(rèn)定義米者。
- non-virtual 函數(shù):你不希望 derived class 重新定義它韭畸。
- 應(yīng)用
-
Template Method
Template Method
-
對(duì)象組合
Inheritance + Composition
- Inheritance + Composition
-
構(gòu)造由內(nèi)而外
- Derived 的構(gòu)造函數(shù)首先調(diào)用 Base 的 default 構(gòu)造函數(shù)宇智,然后調(diào)用 Component 的 default 構(gòu)造函數(shù),最后才調(diào)用自己胰丁。
Derived::Derived(...): Base(), Component() { ... };
-
析構(gòu)由外而內(nèi)
- Derived 的析構(gòu)函數(shù)首先執(zhí)行自己随橘,然后調(diào)用 Component 的析構(gòu)函數(shù),最后調(diào)用 Base 的析構(gòu)函數(shù)锦庸。
Derived::~Derived(...): { ...~Component(), ~Base(); };
Delegation + Inheritance
(1).Observer
Observer
- Subject 包含一個(gè)委托容器 Observer
- Observer 類(lèi)可繼承
- Subject 控制流程机蔗,讓 Observer 的子類(lèi)根據(jù)需求來(lái)注冊(cè)、注銷(xiāo)
(2). Composite
103.png
- Composite---add不能寫(xiě)成純虛函數(shù)酸员,因?yàn)镻rimitive沒(méi)有add的動(dòng)作蜒车,如文件是不能有+的動(dòng)作的讳嘱,只有文件夾才有
(3). Prototype (Design Patterns Explained Simply)
Prototype
創(chuàng)建未來(lái)的對(duì)象幔嗦,需要每個(gè)子類(lèi)自己創(chuàng)建一個(gè)自己給父類(lèi),讓父類(lèi)可以看到
LandSatImage(子類(lèi)) 創(chuàng)建靜態(tài)的自己掛接到框架中-addPrototype
Image(框架)用于創(chuàng)建未知的子類(lèi)-findAndClone
-
代碼圖:
- 負(fù)號(hào)代表private,#代表protected,正好or不寫(xiě)代表public
- 先寫(xiě)名字沥潭,在寫(xiě)類(lèi)型(如果必要)