c++ - 使用模板实现多态

标签 c++ templates inheritance design-patterns

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

我有一个接受模板参数的基类。

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);
};

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

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

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

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

通常我会使用带有 Handler 指针的依赖注入(inject)来解决这个问题,而不是使用模板,但这在很多地方都用到了,我宁愿不改变它。

我还有哪些其他选择?

谢谢

最佳答案

首先想到的是使基类方法成为纯虚拟的:

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
};

关于c++ - 使用模板实现多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24201363/

相关文章:

Java 继承 - 尝试创建通用方法从 Guava EventBus 库获取总线

c++ - 类成员函数的堆栈,但该类尚不清楚

c++ - 在 C++98/C++03 中,如何设置我的类,使其不能从中继承?

c++ - 如何在编译时从字符串文字生成整数?

C++ 11在缺少时提供空的非成员函数

html - 为什么 CSS 样式没有被 HTML 表单字段继承?

c++ - 使用 acm 将 Ogg 转为 Riff/Wave 编码

c++ - 使用 OpenCV 描述符匹配 findFundamentalMat

c++ - 手动对象构造函数调用

c# - 带按钮的 TreeView 多级自定义模板