C++中的保留签名的装饰器图案

Signature-preserving Decorator Pattern in C++?

本文关键字:保留 C++      更新时间:2023-10-16

我想在C++中使用装饰器模式,并且仍然能够依赖装饰对象的签名/身份。可以在C++做到吗?

也就是说,我想装饰一个组件:

class Component {
  public:
      Component();
      virtual void doSomething();
}

带装饰器:

class Decorator : public Component {
  public:
      Decorator(Component*);
      virtual void doSomething();
  private:    
      Component* _component;
}

这样当我这样做时:

Component foo;
Decorator(&foo) bar;
std::cout << typeid(bar).name() << std::endl;

它打印"组件"而不是"装饰器"。

(这实际上非常简单,使用装饰器模块在 Python 中完成,但我目前正在学习C++,甚至不知道从哪里开始寻找这个问题的答案。

如果我想扩展 Component 类但仍能够以透明的方式使用它(好像它不会被扩展),这很有用:

class ExtendDecorator : public Decorator {
  public:
      ExtendDecorator(Component*);
      virtual void doSomething();    
  private:
      void doSomethingMore();
}
void ExtendDecorator::doSomething() {
    Decorator::doSomething();
    doSomethingMore();
}

由于C++不允许重载运算符typeid - 我可以提出的唯一解决方案是为装饰类型添加返回type_info的虚拟方法:

class Component {
  public:
      Component();
      virtual void doSomething();
      virtual const std::type_info& decorated_type() const 
      { return typeid(*this); } 
};
class Decorator : public Component {
  public:
      Decorator(Component*);
      virtual void doSomething();
      virtual const std::type_info& decorated_type() const 
      { return typeid(*_component); } 
  private:    
      Component* _component;
};

也许更好的版本Decorator::decorated_type() const

virtual const std::type_info& decorated_type() const 
{ return _component->decorated_type(); }