Object Oriented Programming and Object Oriented Design(面向?qū)ο缶幊毯驮O(shè)計(jì))
本章內(nèi)容:
1 組合與繼承
2 虛函數(shù)與多態(tài)
3 委托相關(guān)設(shè)計(jì)
1 組合與繼承
- 在該節(jié)中包含了三種關(guān)系:
(1). Composition(復(fù)合)
(2). Delegation(委托)
(3). Inheritance(繼承)
(1) Composition(復(fù)合)
- 復(fù)合表示
has-a關(guān)系,例如queue包含deque,代碼如下所示:

-
復(fù)合關(guān)系下的構(gòu)造和析構(gòu),下圖中
Container包含Component,UML圖和對(duì)象結(jié)構(gòu)圖如下所示:
UML和對(duì)象結(jié)構(gòu)圖 構(gòu)造由內(nèi)而外:
-
Container的構(gòu)造函數(shù)首先調(diào)用Component的default構(gòu)造函數(shù),然后再執(zhí)行自己的構(gòu)造函數(shù),如下所示:Container::Container(...) : Component() {...} 其中
Component()是編譯器默認(rèn)添加上去的。析構(gòu)由外而內(nèi):
-
Container的析構(gòu)函數(shù)首先執(zhí)行自己的析構(gòu)函數(shù),然后再調(diào)用Component的析構(gòu)函數(shù),如下所示:Container::~Container(...) {... ~Component(); } 其中
~Component()是編譯器默認(rèn)添加上去的。
(2) Delegation(委托)
-
委托可以用Composition by reference表示,其中Composition by reference在這表示指針的意思,UML圖如下所示:
Delegation(委托) -
經(jīng)典的pImpl(point to implement)或Handle/Body模式,如下代碼所示:
class StringRep; class String { public: String(); String(const char* s); String(const String& s); String& operator=(const String& s); ~String(); ...... private: StringRep* rep; // pImpl }; class StringRep { public: friend class String; StringRep(const char* s); ~StringRep(); private: int count; char* rep; }; String::String() { ... } ...... 這個(gè)pImpl俗稱(chēng)“編譯防火墻”,其可以用一個(gè)指針指向一個(gè)類(lèi),
StringRep類(lèi)實(shí)現(xiàn)了具體的方法功能,String類(lèi)只調(diào)用StringRep類(lèi)的指針來(lái)實(shí)現(xiàn)其定義的接口,如此一來(lái)對(duì)外接口可以保持不變,而具體的實(shí)現(xiàn)部分可以根據(jù)實(shí)際要求來(lái)用不同的方式實(shí)現(xiàn),從而達(dá)到了接口和實(shí)現(xiàn)隔離的效果。
(3) Inheritance(繼承)
-
繼承表示
is-a關(guān)系,如下圖表示:
is-a關(guān)系圖 -
繼承關(guān)系下的構(gòu)造和析構(gòu):
UML和對(duì)象結(jié)構(gòu)圖 構(gòu)造由內(nèi)而外:
-
Derived的構(gòu)造函數(shù)首先調(diào)用Base的defaule構(gòu)造函數(shù),然后再執(zhí)行自己的構(gòu)造函數(shù),如下代碼所示:Derived::Derived(...) : Base() { ... } 其中
Base()是編譯器默認(rèn)添加上去的。析構(gòu)由外而內(nèi):
-
Derived的析構(gòu)函數(shù)首先執(zhí)行自己的構(gòu)造函數(shù),然后再調(diào)用Base的析構(gòu)函數(shù),如下代碼所示:Derived::Derived(...) { ... ~Base() } 其中
~Base()是編譯器默認(rèn)添加上去的。
注意:base class的destructor必須是virual的,否則會(huì)造成內(nèi)存泄漏或其他沒(méi)有定義的行為。
2 虛函數(shù)與多態(tài)
Inheritance(繼承) with virtual functions(虛函數(shù))
(1).non-virtual函數(shù):你不希望derived class重新定義(override,覆寫(xiě))它。
(2).virtual函數(shù):你希望derived class重新定義(override,覆寫(xiě))它,且你對(duì)它已有默認(rèn)定義。
(3).pure virtual函數(shù):你希望derived class一定要重新定義(override,覆寫(xiě))它,你對(duì)它沒(méi)有默認(rèn)定義。-
三種
functions的代碼表示方式如下圖:
virtual functions虛函數(shù) -
Inheritance+Composition關(guān)系下的構(gòu)造和析構(gòu)
(1) Derived has a Component & Derived is a Base,UML圖如下所示:
UML圖 構(gòu)造由內(nèi)而外:
Derived的構(gòu)造函數(shù)首先調(diào)用Base的default構(gòu)造函數(shù),然后調(diào)用Component的構(gòu)造函數(shù),最后執(zhí)行自己的構(gòu)造函數(shù)。析構(gòu)由外而內(nèi):
-
Derived的析構(gòu)函數(shù)首先執(zhí)行自己的構(gòu)造函數(shù),然后調(diào)用Component的析構(gòu)函數(shù),最后調(diào)用Base的析構(gòu)函數(shù)。(2) Derived is a Base & Base has a Component,UML圖如下所示:
UML圖 構(gòu)造由內(nèi)而外:
Derived的構(gòu)造函數(shù)首先調(diào)用Component的構(gòu)造函數(shù),然后調(diào)用Base的default構(gòu)造函數(shù),最后執(zhí)行自己的構(gòu)造函數(shù)。析構(gòu)由外而內(nèi):
Derived的析構(gòu)函數(shù)首先執(zhí)行自己的構(gòu)造函數(shù),然后調(diào)用Base的析構(gòu)函數(shù),最后調(diào)用Component的析構(gòu)函數(shù)。
3 委托相關(guān)設(shè)計(jì)
Delegation(委托)+Inheritance(繼承)
-
委托+繼承的用法之
Observe(觀(guān)察者)模式,UML圖如下所示:
觀(guān)察者模式UML圖 -
具體代碼示例如下:
class Observer { public: virtual void update(int value) = 0; }; class Subject { private: int m_value; vector<Observer*> m_views; public: void attach(Observer* obs) { m_views.push_back(obs); } void set_val(int value) { m_value = value; notify(); } void notify() { for (int i=0;i<m_views.size();i++) { m_views[i]->update(m_value); } } }; // 繼承觀(guān)察者類(lèi) class Observer1 : public Observer { private: int m_div; public: Observer1(Subject* model, int div) { model->attach(this); m_div = div; } void update(int v) { ... } }; class Observer2 : public Observer { private: int m_mod; public: Observer2(Subject* model, int mod) { model->attach(this); m_mod= mod; } void update(int v) { ... } }; // 使用詳解 int main(void) { Subject subj; Observer1 o1(&subj, 4); Observer1 o2(&subj, 3); Observer2 o3(&subj, 3); subj.o1(14); } -
(2) 委托+繼承的用法之
Composite(組合)模式,UML圖如下所示:
組合模式UML圖 -
具體代碼示例如下:
class Component { private: int value; public: Component(int val) { value = val; } virtual void add(Component*) {} }; class Composite : public Component { private: vector<Component*> c; public: Composite(int val) : Component(val) {} void add(Component* elem) { c.push_back(elem); } ...... }; class Primitive : public Component { public: Primitive(int val) : Component(val) {} };








