面向?qū)ο缶幊毯驮O(shè)計(jì)

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,代碼如下所示:
has-a關(guān)系圖
  • 復(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)用Componentdefault構(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)用Basedefaule構(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 classdestructor必須是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)用Basedefault構(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)用Basedefault構(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) {}
      };
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容