目录
条款35 Consider alternatives to virtual functions
藉由 Non-Virtual Interface 手法实现 Template Method 模式
藉由 Function Pointers 实现 Strategy 模式
藉由 trl: :function 完成 Strategy 模式
条款36 Never redefine an inherited non-virtual function
条款37 Never redefine a function's inherited default parameter value
条款38 Model "has-a" or "is-implemented-in-terms-of" through composition(复合)
条款35 Consider alternatives to virtual functions
考虑virtual函数之外的选择
藉由 Non-Virtual Interface 手法实现 Template Method 模式
令客户通过public non-virual成员函数间接调用private virtual函数,即 Non-Virtual Interface 手法(NVI)。这个non-virtual函数被称为virtual函数的wrapper。
Eg.
NVI好处之一就是可以做一些“事前工作”和“事后工作”。比如锁定互斥器,互斥器解除锁定,制造运转日志记录项等等。
NVI手法下不一定要virtual函数是private,有些derived class在virtual函数时需要调用其base class的virtual函数,这样virtual函数就必须是protected
藉由 Function Pointers 实现 Strategy 模式
将virtual 函数替换为"函数指针成员变量"
成员为一个函数指针
藉由 tr1: :function 完成 Strategy 模式
将函数指针使用对象代替上述的Funtion Pointer的实现
使用tr1::function代替virtual函数,因而允许使用任何可调用物搭配一个兼容于需求的签名式
古典的 Strategy 模式
条款36 Never redefine an inherited non-virtual function
不要重定义一个继承的non-virtual函数
有代码如下
此时pB->mf()和pD->mf()调用的mf函数不同,因为non-virtual函数使用的是静态绑定,一个使用的是B::mf(),另一个使用的是D::mf()。
而如果在mf前加上virtual,不管把x定义成B还是D的指针,调用的mf()都是D::mf()
条款37 Never redefine a function's inherited default parameter value
绝不重定义继承而来的默认参数值
此处讨论的是继承的virtual函数。
virtual函数是动态绑定,而默认参数是静态绑定。
条款38 Model "has-a" or "is-implemented-in-terms-of" through composition(复合)
如图所示,这就是一个复合类型,Person类中包含了Address类和PhoneNumber类,其中内在含义是Person has address and phone number.
复合意味着“has-a”,即有一个,或者“is-implemented-in-terms-of”(根据某物实现出)
is-implemented-in-terms-of可以使用STL的queue举例:queue实现使用了deque,所以创建类时不应该写class queue:public deque,而是
template<class T>
class Queue {
private:
Deque <T> de;
public:
void push();
bool empty();
...
}