Modern C++ design 第5章 Command 设计模式
命令模式将发出命令的责任和执行命令的责任分离开来
Command模式两个特点
接口分类;
时间分离。Command保存了一个整装待发的处理请求,供将来运用。Command模式中,收集“某处理动作所需环境”的时刻和执行该动作的时刻并不相同。
可以将Command分为两类
1.转发式命令forwarding command
2.主动式命令active command
C++中支持operator()的所有构件:
1. C-like function(C风格函数)
2. C-like pointer to function(C风格的函数指针)
3. reference to function,指向函数的引用
4. functor(仿函数),即自行定义了operator()的一种对象
5. operator.*或operator->*的施行结果。
6. construct call(构造函数)
设计思想,首先思考下对函数指针的封装,要做到通用,那就必须知道传入的函数指针的类型,应该要让编译器自动推导出来,而类模板是不允许推导的,只有函数可以进行参数推导,故在设计类的时候,可以在构造函数中使用模板推导,而要做到对operator()的封装,那必须传入返回值和参数,这两个模板参数,于是便有了如下的声明:
#pragma once#include <iostream>#include <memory>class Animal {public:virtual void Speak() = 0;virtual Animal * DoClone() const = 0;virtual ~Animal() { }};#define DEFINE_CLONE_ANIMAL(Cls) \virtual Cls * DoClone() const { return new Cls(*this); }class Bird : public Animal{public:virtual void Speak() { std::cout << "I am a bird.\n"; }DEFINE_CLONE_ANIMAL(Bird);};class Fish : public Animal{public:virtual void Speak() { std::cout << "I am a fish.\n"; }DEFINE_CLONE_ANIMAL(Fish);};class AnimalHolder{public:AnimalHolder(AnimalHolder const &rhs) : spImpl_( rhs.spImpl_->DoClone() ) {}AnimalHolder(Animal * spImpl ) : spImpl_( std::auto_ptr<Animal>(spImpl) ) { }void Speak() { spImpl_->Speak(); }private:std::auto_ptr<Animal> spImpl_;};