GoF装饰器模式使用c++中的静态多态性(模板)
GoF decorator pattern using static polymorphism (templates) in c++
decorator模式是一种众所周知的模式,用于在不影响同类其他对象功能的情况下扩展对象的功能。如何在继承较少的情况下使用此模式(使用模板)?
基本上,多态装饰器的抽象接口变成了一个隐式定义的概念,并且嵌套了类型。例如:
struct BasicCoffee
{
void print() {std::cout << "Coffee!n";}
};
template <class T>
struct CreamDecorator
{
CreamDecorator(T x) : mNested(x) {}
void print() {mNested.print(); std::cout << "..with cream!n";}
T mNested;
};
template <class T>
struct SugarDecorator
{
SugarDecorator(T x) : mNested(x) {}
void print() {mNested.print(); std::cout << "..with sugar!n";}
T mNested;
};
您可能想使用对象生成器习惯用法来简化合成:
template <class T>
CreamDecorator<T> addCream(T x) {return CreamDecorator<T>(x);}
template <class T>
SugarDecorator<T> addSugar(T x) {return SugarDecorator<T>(x);}
由于没有通用类型来存储装饰对象,因此需要使用某种类型推断。例如:
auto myCoffee = addSugar(addCream(BasicCoffee()));
myCoffee.print();
或者,使用您从对象生成器中获得的值作为右值(如果您一直使用C++03,这可能很有用——类型擦除也有帮助!):
addSugar(addCream(BasicCoffee())).print();
如果不显式包装正在装饰的东西的所有公共方法,就无法做到这一点。举个例子:
#include <iostream>
using namespace std;
class Test {
public:
void foo() { cout << "Foo" << endl; }
void bar() { cout << "Bar" << endl; }
};
template <typename T>
class FooDecorator {
public:
explicit FooDecorator(T &t) : t(t) {}
void foo() {
cout << "Baz ";
t.foo();
}
void bar() { t.bar(); }
private:
T &t;
};
template <typename T>
class BarDecorator {
public:
explicit BarDecorator(T &t) : t(t) {}
void foo() { t.foo(); }
void bar() {
cout << "Baez ";
t.bar();
}
private:
T &t;
};
int main() {
Test test;
BarDecorator<FooDecorator<Test> > bd(FooDecorator<Test>(test));
bd.foo();
bd.bar();
}
如果在decorator中删除bar
的(无用的)装饰,编译将失败。抛开这个复杂因素不谈,这是完全可行的。。。除了所有接受可适配实体的函数现在也必须被模板化之外。所以最后我不建议走这条路。
这种方法的另一个缺点是,即使你只修饰引用,也必须为你最终使用的所有模板专门化生成代码,因为如果没有vtable,编译器将无法统一处理具有相同名称的不同类的方法;如果你让你的类从一个声明这些方法为虚拟的父类继承,那么使用模板就没有什么好处了——你可能会获得性能,但也可能会失去它,因为更多的代码会在缓存中膨胀。
相关文章:
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 关于 CRTP 静态多态性的困惑
- 混合双重调度和静态多态性
- CRTP 静态多态性:是否可以用模拟替换基类
- 将静态访问者与静态多态性层次结构相耦合
- 静态多态性和方法名称 c++
- 静态多态性策略和CRTP有什么区别
- 静态多态性与boost变体单访问者与多访问者与动态多态性
- 静态多态性问题
- 静态多态性中的纯抽象函数等价物是什么
- 使用CRTP在静态多态性中模拟纯虚拟函数是可能的
- C++静态多态性背后的动机是什么?
- 为什么AbstractFactoryUnit具有动态多态性而不是静态多态性
- C++中的静态多态性
- c++中方法和对象选择的静态多态性
- 静态多态性中的歧义(2)
- 静态多态性中的模糊性
- 使用CRTP的静态多态性:使用基类调用派生方法
- c++装饰器模式,带有模板的静态多态性和注册回调方法
- 静态多态性——在c++中这是一个正确的多态场景吗?