复合,继承,委托

复合(Composition)

复合其实是一种 has-a 的关系,就是说一个类里面有其他类的对象
例如在STL标准库的实现中,queue里面有一个deque

template <class T>
class queue {
    //...
protected:
    deque<T> c;
public:
    //以下功能完全利用 c 的操作函数完成
    bool empty() const { return c.empty(); }
    size type size() const { return c.size(); }
    //
    void push(const value_type& x) { c.push_back(x); }
    void pop() { c.pop_front(); }  
};

queue的一些功能完全借助deque来实现。

复合关系下的构造与析构

  1. 构造函数是由内而外
    Container的构造函数首先调用Component的default构造函数(编译器帮助我们做的)
    然后才执行自己
          Container::Container{...}:Component(){...}
  1. 析构是由外而内
    Container的析构函数首先执行自己,然后才调用Component的析构函数
          Container::~Container{...}{... ~Component() };

如果不想调用另一个对象的默认构造函数,那就要显示调用

继承(Inheritance)

继承是一种 is-a 的关系,
基类中函数有三种:
- 普通函数
- 虚函数
- 纯虚函数
其中,如果在基类中写成纯虚函数,那么派生类(derived class)中一定要重新定义该函数,就是说派生类要有该虚函数的自己的版本
如果是虚函数,那么在基类中已经有了默认定义,派生类中可以选择重新定义。
public继承下,父类中的数据是被完全继承下来的。

继承关系的构造与析构

  1. 构造由内而外
  2. 析构由外而内

继承关系下构造与析构顺序与复合关系下相同。
当一个类同时有继承和复合时,是先调用基类的构造函数还是另一个复合的类的构造函数呢?
析构函数的顺序呢?谁先谁后并不重要,只是看一下。
一个测试程序看一下结果

#include <iostream>
using namespace std;

class Base{
public:
    Base()
    {
        cout << "I'm base class!" << endl;
    }
    ~Base()
    {
        cout << "Base dead!" << endl;
    }
};

class Com{
public:
    Com()
    {
        cout << "I'm Composition class!" << endl;
    }
    ~Com()
    {
        cout << "Composition dead!" << endl;
    }
};

class Test:public Base{
public:
    Test()
    { 
        cout << "I'm Test class!" << endl;
    }
    ~Test()
    {
        cout << "Test class dead!" << endl;
    }
    Com ch;
};

int main()
{
    Test tt;
    return 0;
}

以下是在windows下使用Dev-c++,GCC 4.9.2的执行结果:
这里写图片描述
构造函数执行顺序是先执行基类的构造函数,再执行复合的对象的构造函数
析构函数执行顺序是先执行复合的对象的析构函数,再执行基类的析构函数
以上说明基类是“最里面的”
也刚好验证了上面所说的构造是由内到外,析构是由外到内

委托(Delegation)

A类中有一根指向另一个类B的指针
当创建A类对象时,B类对象并不被也创建,而在复合关系中,两个类的对象是同时创建
委托关系可以委托B类帮自己具体实现,

这种方法有个名词pImpl(Pointer to IMPLementation),简单理解就是接口与实现分离

(后面继续再整理)

猜你喜欢

转载自blog.csdn.net/chuxin126/article/details/78217542