1、composition(复合)

    template<class T, class Sequence = deque<T>>
    class stack
    {
        friend bool operator==<> (const stack &, const stack&);
        friend bool operator< <> (const stack&, const stack&);
    public:
        typedef    typename Sequence::value_type    value_type;
        typedef    typename Sequence::size_type    size_type;
        typedef    typename Sequence::reference    reference;
        typedef    typename Sequence::const_reference    const_reference;
    protected:
        Sequence c;    //底层容器 deque<T>,以下操作完全由底层容器代为操作
    public:
        bool empty() const { return c.empty(); }
        size_type size() const { return c.size(); }
        reference top() const { return c.back(); }
        void push(const value_type&x) { c.push_back(x); }
        void pop(){ c.pop_back(); }

    };

画图表示

 

 

复合关系下的构造和析构:

  stack的构造函数首先会调用deque的构造函数,然后再执行自己的构造函数。析构则相反。下面是个测试程序,man中含有一个person

class person
{
public:
    person()
    {
        cout << "person的默认构造函数" << endl;
    }
    person(string name, int age) :m_name(name), m_age(age)
    {
        cout << "person的有参构造函数" << endl;
    }
    ~person()
    {
        cout << "person的析构函数" << endl;

    }
private:
    string m_name;
    int m_age;
};
class man
{
public:
    man()
    {
        cout << "man的默认构造函数" << endl;
    }
    man(string name, int age) :p(name, age)
    {
        cout << "man的有参构造" << endl;
    }
    ~man()
    {
        cout << "man的析构函数" << endl;
    }
private:
    person p;   //man class中有person
};
void test01()
{
    man haha("liming", 12);

}

打印结果:

 2、delegation(委托)

  delegation和composition很像。A类的内部拥有的是B类的指针,对B类做修改并不影响A类的接口。

  一个测试程序

class person
{
public:
    person()
    {
        cout << "person的默认构造函数" << endl;
    }
    person(string name, int age) :m_name(name), m_age(age)
    {
        cout << "person的有参构造函数" << endl;
    }
    void showinfo() const
    {
        cout << "name:" << m_name << "," << "age:" << m_age << endl;
        cout << "这是我做的修改" << endl;
    }
    ~person()
    {
        cout << "person的析构函数" << endl;

    }
private:
    string m_name;
    int m_age;
};
class man
{
public:
    man()
    {
        p = new person;
        cout << "man的默认构造函数" << endl;
    }
    man(string name, int age) 
    {
        p = new person(name, age);
        cout << "man的有参构造" << endl;
    }
    void showname() const
    {
        p->showinfo();
        
    }
    ~man()
    {
        if (p != NULL)
        {
            delete p;
            p = NULL;
        }
        cout << "man的析构函数" << endl;
    }
private:
    person *p;
};
void test01()
{
    //man haha;
        mam haha("liming",12);
        haha.showname();
}

画图表示:

3、继承

  子类内部拥有父类的成分。构造的时候由内到外,析构由外到内。子类拥有父类的数据,拥有父类的函数调用权。而父类中函数可以分为三类函数:1、non-virtual函数:不希望子类可以重写他;2、virtaul函数,子类可以重写,父类有默认的定义;3、pure virtual 子类必须重写,父类没有定义。

class animal
{
    virtual void speak() = 0;  //纯虚函数,子类必须重写
    virtual void eat()    //虚函数,子类可以重写
    {
        cout << "吃肉" << endl;
    }
    void run()
    {
        cout << "走路" << endl;
    }
};
class cat :public animal
{};
class sheep :public animal
{};

   这里衍生出的一个经典的设计模式——template method

  把不变的部分先写好,动态变化的部分留给编写应用程序的人来编写。

 1 //相当于library
 2 class CDocument
 3 {
 4 public:
 5     void onFileOpen()
 6     {
 7         cout << "dialog..." << endl;
 8         cout << "check file..." << endl;
 9         cout << "open file.." << endl;
10         Serialize();//动态变化的部分
11         cout << "close file..." << endl;
12     }
13     virtual ~CDocument(){}
protected:
14     virtual void Serialize()=0;
15 };
16 //application
17 class CMyDoc:public CDocument
18 {
19 public:
20     void Serialize() //子类重写
21     {
22         cout << "CMyDoc::serialize..." << endl;
23     }
24 };
25 int main()
26 {
27     CMyDoc mydoc;
28     mydoc.onFileOpen(); //子类对象调用父类函数
29 }