11 组合与集成
结束单个class设计,开始设计class直接的关系。
主要学习三种关系:Inheritance(继承)、Composition(复合)、Delegation(委托)。
复合Composition:
一个class里面有一个成员是class(has-a 有一个),类似C语言结构体套结构体。
图说queue里面有一个deque:
queue拥有deque,queue的所有功能都让deque实现。
queue是单向队列,deque是双向队列。
复合后内存变化:
复合情况下的构造函数与析构函数:
使用Container和Component这两个泛化的名称举例
构造时:(由内而外构造)
Conatiner先调用Component的默认default构造函数执行,在执行自己的构造函数。
Container::Container( … ) : Component() {…}; 红色部分编译会加上去。
默认default:当想自己选择是需要自己加代码。
析构时:(由外而内析构)
Container先执行自己的析构,在调用Component的析构函数。
Container::~Container( … ) { … ~ Component() };红色部分编译会加上去。
洋葱一样。
委托Delegation:
当类的成员里有个class的指针时,可以称之为Delegation:
一边是个Handle,一边是个Body:
委托只是拥有一个暂时不存在的class,这样的两个class的生命周期将会不同。
继承Inheritance:
继承(is-a是一个)。
图说:
继承分为父类和子类,子类的数据中有父类的成分:
构造时:(由内而外构造)
Derived的构造函数首先调用base的default默认构造函数,然后才执行自己。
Derived::Derived(…) : Base() { … }; 红色部分由编译器负责。
析构时:(由外而内析构)
Derived的析构函数首先执行自己,然后调用Base的析构函数。
Derived::~Derived(…) { … ~Base()};红色部分由编译器负责。
与复合Composition相同。
父类的析构函数必须是虚函数,否则将出现undefined behavior。
12 虚函数与多态
虚函数:
non-virtual函数 | 不希望继承者derived class重新定义(override); |
virtual函数 | 希望继承者重新定义override,而在此之前已经有了定义; |
pure virtual函数 | 希望继承者一定要重新定义,因为父类没有定义,只是声明。 |
虚函数可以用来设计框架。
一种虚函数设计CDocument:
子类CmyDoc重写Serilize:
当既有继承(Inheritance)又有复合(Composition)时,构造和析构的先后顺序:
先创建“父”,再创建“朋友”,最后创建“子”。
先析构“子”,在析构“朋友”,最后析构“父”。
在类的三种关系中,功能最强大的时委托(Delegation)+继承(Inheritance)
设计方法,数据class包含N个观察class(委托),使用vector包含N个观察class的地址。数据每发生一次变化,for循环执行一次所有观察class的update函数。
13 委托相关设计
c++常见23种设计模式,问题和解法。
Composite设计模式:A继承B,同时A中由有B的指针(委托)。
Prototype设计模式:现在在父类中,要创建未来才创建的对象。在父类的函数中new未知的子类。父类准备一个static地址空间,子类将new出来的原型放入这个空间。此时要求子类的构造函数应该是private