简单的子类模板模式

Simple subclass template pattern

本文关键字:模式 子类 简单      更新时间:2023-10-16

我有一些带有虚拟方法foo()Base类。我需要生成几个结构完全相同的子类,并以不同的方式简单地覆盖foo()。我想出了一个简单的非类型参数模板:

template<const int Index>
class Derived : public Base
{
  virtual void foo() {....};
};

typedef Derived<1> Derived_1;
typedef Derived<2> Derived_2;
...
...

然后方法CCD_ 4专门用于每种情况。

我对这种策略并不完全满意,因为你需要小心索引冲突(尽管这没什么大不了的),并且实现文件会失去可读性,因为你必须知道索引"2"或"3"对应的是什么。最好使用字符串

typedef Derived<"Derived_2"> Derived_2;

但是字符串文字不允许作为模板参数。

在这种情况下,这是推荐使用的模式吗?有更好的吗?(也许这是一个已知的模式,甚至有名字,但我不知道该找什么。)

似乎用继承来建模这种关系更接近于您试图实现的语义。

struct Derived1 : Derived
{
  using Derived::Derived; 
  virtual void foo() {
      std::cout << "Derived1" << std::endl;
  };
};
struct Derived2 : Derived
{
  using Derived::Derived;
  virtual void foo() {
      std::cout << "Derived2" << std::endl;
  };
};

有了这个版本,您可以很高兴地将任何DerivedN版本用作Derived对象,因此在它们之间转换或在不同版本上一起操作比将所有跨派生成员函数作为模板更容易。

using Derived::Derived;声明是继承Derived可能具有的任何非默认构造函数所必需的。

我建议使用枚举作为模板参数:

enum class type {foo, bar};
template<type name>
class Derived //...
{};
typedef Derived<type::foo> Derived_foo;

使用预处理器定义:可以做得更清楚

#define DERIVED1 1
#define DERIVED2 2
typedef Derived<DERIVED1> Derived_1;
typedef Derived<DERIVED2> Derived_2;

或者可能使用enum?(我不确定,你应该测试一下)。

但不要犹豫,在代码中记录它,这可能是最好的方法。

用define代替数字怎么样?至少它更清楚了。

#define DERIVED_2 2
typedef Derived<DERIVED_2> Derived_2;

但目前还不清楚派生类之间的区别,它们肯定不仅仅是数字。