zoukankan      html  css  js  c++  java
  • 面向对象(类和类之间的关系)--继承(虚函数的调用时的隐藏this)、复合、委托

    1、复合Composition(has-a关系,一个类中包含另一个类的对象)

      构造时,由内到外,析构时,由外到内。

      

      Adapter设计模式,queue是deque的adapter。因为deque完全含有queue的所有功能,queue就是在deque上面设计的。

     1 template<class T,class Sequence = deque<T>>
     2 class queue{
     3     ...
     4     protected:
     5         Sequence c;//复合关系
     6     public:
     7         bool empty() const {return c.empty();}
     8         size_type size() const {return c.size();}
     9         reference front() {return c.front();}
    10         reference back(){ return c.back();}
    11         void push(const value_type& x) {c.push_back(x);}
    12         void pop () { c.pop_front();}
    13 };
    14 template<class T> //同上面相同功能,不同形式
    15 class queue{
    16     ...
    17     protected:
    18         deque<T> c;
    19     ...
    20 };

    2、委托Delegation(一个类中含有另一类的指针)

        

      Handke/Body(pImpl) ------>扩展出引用计数和写时拷贝

        

    class StringRep;
    class String{
        public:
            String();
            String(const char*s);
            String(const String&s);
            String& operator=(const String& s);
            ~String();
            ...
        private:
            StringRep *rep; //有一个handle,body有很好的可扩展性。
    };

    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;
    };

        ①non-virtual 函数:不希望子类重新定义它

        ②virtual函数:可以有默认定义,但希望子类去重新定义它。(有virtual的类,析构函数一定要设计成virtual)

        ③pure virtual函数:希望子类一定要重新定义它。(含有纯虚函数的类不能直接生成对象)

    4、Template Method(父类的成员函数实现中含有一个虚函数,这个虚函数由子类去实现)

      调用父类的成员函数时传入一个隐藏的this(子类的this指针),由this去调用虚函数,则调用的是子类的虚函数

      

     5、继承并且复合时 Inheritance+Composition(构造时:先构造父类再构造复合类,析构时:先析构复合类再析构父类)

        

    #include<iostream>                                                                   
    class A{                                                                                                
      private :                                                                          
        int a ;                                                                          
      public :                                                                           
        A(){std::cout << "A is start" << std::endl;}                                     
        ~A(){std::cout << "A is finsh 
    ";}                                              
    };                                                                                   
    class B{                                                                             
      private:                                                                           
        int b;                                                                           
      public:                                                                            
        B(){std::cout << "b is start
    ";}                                                
        ~B(){std::cout << "b is finsh 
    ";}                                              
    };                                                                                   
    class C : public A{                                                                  
      private:                                                                           
        B ins ;                                                                          
      public:                                                                            
      C(){std::cout << "c is start 
    ";}                                                 
      ~C(){std::cout << "c is finsh 
    ";}                                                
    };                                                                                   
    int main(){                                                                          
      C c ;                                                                              
      return 0;                                                                          
    } 

    6、继承加委托 Inheritance+ Delegation

       观察者模式Observer(Observer去观察Subject,当Subject发生改变时,用notify调用update去通知Observer,update由观察者自己实现。)

        以ppt的编写为例:ppt的内容改变后,其左边的缩略图也会被改变,ppt的内容为Subject,缩略图为Observer

      

    class Observer                                                                       
    {                                                                                    
      public:                                                                            
        virtual void update(Subject* sub,int value) = 0;                                 
    }                                                                                    
    class A : public Observer                                                            
    {                                                                                    
        void update(Subject* sub, int value){                                            
          ....                                                                                              
        }                                                                                
    }                                                                                    
    class B : public Observer                                                            
    {                                                                                    
        void update(Subject* sub, int value){                                            
          ....                                                                           
        }                                                                                
    }                                                                                    
    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;                                                               
          motify();                                                                      
        }                                                                                
        void notify()                                                                    
        {                                                                                
          for(int i = 0; i < m_views.size();++i)                                         
            m_views[i]->update(this,m_value);                                            
        }                                                                                
    }  

      Composite模式(右边子类中含有父类的多个指针,这多个指针既可以指向左边的子类,也可以指向右面的子类)

        以文件系统为例:左边的子类是文件类,右边的子类是目录类,目录中可以添加一个目录或文件,而文件中不能添加任何目录或文件。在这里父类的add函数不能设置为pure virtual,因为pure virtual必须要被子类实现。

       

     1 class Component{                                                                  
     2   private:                                                                        
     3     int value;                                                                    
     4   public:                                                                         
     5     Component(int val) : value(val){}                                             
     6     virtual void add (Component*) {}                                              
     7 };                                                                                
     8 class Primitive : public Component {                                              
     9   public:                                                                         
    10     Primitive(int value) ; Component(val){}                                       
    11 };                                                                                
    12 class Composite : public Component{                                               
    13   private:                                                                        
    14     std::vector<Component* > c ;                                                  
    15   public:                                                                         
    16     Composite(int val):Component(val){}                                           
    17     void add(Component* elem){ //这个elem可以是左边类的实例,也可以是右边类的实例                                                 
    18       c.push_back(elem);                                                                                
    19     }                                                                             
    20 }

    7、动态绑定(必须满足:通过指针调用,指针向上转型,调用虚函数)。

      (*(this->vptr)[n])(this)

  • 相关阅读:
    Daily Scrum 10.26
    Daily Scrum 10.25
    Daily Scrum 10.24
    Week7 Teamework from Z.XML-任务分配
    Daily Scrum 10.23
    软件工程项目组Z.XML会议记录 2013/10/22
    Week7 Teamework from Z.XML-NABC
    cocos2d-x环境搭建 摘自百度文库
    Go 接口
    Auto-Scaling Web Applications in Clouds: A Taxonomy and Survey读书笔记
  • 原文地址:https://www.cnblogs.com/Ccluck-tian/p/11885348.html
Copyright © 2011-2022 走看看