使用模板实现多态性

Using templates for polymorphism

本文关键字:实现 多态性      更新时间:2023-10-16

所以我在一些遗留代码中得到了一些编译时多态性。即

我有一个基类要使用,它接受一个模板形参。

template<typename HANDLER>
class Base
{
  virtual HANDLER * make_handler();
  // other methods
};

make_handler使用一个接受两个参数的特定构造函数来构造HANDLER。

处理程序通常是我们唯一需要更改的代码共享,它只做一个方法std::size_t handle_data(const char *, std::size_t length);作为入口点

class SpecificHandler
{
  SpecificHandler(uint32_t id, uint32_t source_id);
  std::size_t handle_data(const char *, std::size_t length);
  // other methods
};
使用的

class Child : public Base<SpecificHandler>
{
  // other overridden methods
};

问题是我想在我的SpecificHandler类中传递另一个参数,即

class OtherSpecificHandler
{
  OtherSpecificHandler(uint32_t id, uint32_t source_id, uint32_t other_id);
};

不幸的是,基类调用模板中的两个参数构造函数。

我目前的工作是覆盖make_handler()调用,返回用3个参数构造函数创建的处理程序,即

class Child : public Base<OtherSpecificHandler>
{
  virtual OtherSpecificHandler * make_handler();
  // other overridden methods
};

不幸的是,因为模板的东西是在编译时完成的,所以我仍然必须提供2个参数的构造函数(实际上我只是为第三个参数提供了一个默认参数),这感觉不对。

通常情况下,我会用Handler的指针依赖注入来解决这个问题,而不是使用模板,但这在很多地方使用,我宁愿不改变它。

我还有其他选择吗?

谢谢

首先想到的是将基类方法设置为纯虚方法:

template<typename HANDLER>
class Base
{
  virtual HANDLER * make_handler() = 0;
  //other stuff
};
这当然意味着每个派生类都必须重载make_handler,即使每个其他处理程序类都具有相同的双参数构造函数。为了避免重复,在层次结构中插入另一个层:
template<typename HANDLER>
class BaseWithStandardHandlerConstruction : public Base<Handler>
{
  virtual HANDLER * make_handler() override //maybe final as well?
  {
    return new HANDLER("meow", 4);
  }
  //that's it - nothing else goes here...
};

则任何具有"普通"处理程序的类派生自后者,而具有"特殊"处理程序的类派生自前者:

class Child : public BaseWithStandardHandlerConstruction<SpecificHandler>
{
  // other overridden methods, no make_handler needed
};
class OtherChild : public Base<OtherSpecificHandler>
{
  virtual OtherSpecificHandler * make_handler() override;
  // other overridden methods
};

您可以模板专门化Base

之类的
template <>
OtherSpecificHandler* Base<OtherSpecificHandler>::make_handler() {
    return new OtherSpecificHandler(42, 5, 12); // With correct parameter ofc.
}