面向对象(类和类之间的关系)--继承(虚函数的调用时的隐藏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)

原文地址:https://www.cnblogs.com/Ccluck-tian/p/11885348.html