如何在创建时自动注册一个类

AMC*_*der 15 c++ design-patterns idioms

我想知道是否存在自动注册类类型的设计模式或习惯用语.或者更简单,我可以通过简单地扩展基类来强制一个方法来调用类吗?

例如,假设我有一个基类Animal和扩展类TigerDog,和我有打印出扩展的所有类的辅助功能Animal.

所以我可以这样:

struct AnimalManager
{
   static std::vector<std::string> names;
   static void registerAnimal(std::string name) { 
            //if not already registered
            names.push_back(name); }
};

struct Animal
{
   virtual std::string name() = 0;
   void registerAnimal() { AnimalManager::registerAnimal(name()); }
};
struct Tiger : Animal
{
   virtual std::string name() { return "Tiger"; }
};
Run Code Online (Sandbox Code Playgroud)

基本上我会这样做:

Tiger t;
t.registerAnimal();
Run Code Online (Sandbox Code Playgroud)

这也可以用于static函数.是否有任何模式(如奇怪的递归模板)或类似的东西可以帮助我实现这一点,而无需显式调用该registerAnimal方法.

我希望class Animal将来可以扩展,其他人可能会忘记打电话register,我正在寻找方法来防止这种情况,除了记录这一点(无论如何).

PS这只是一个例子,我实际上并没有实施动物.

Luc*_*ore 16

你确实可以使用奇怪的递归模板习语来做到这一点.它不需要扩展无法由编译器强制执行的类的任何人:

template<class T>
struct Animal
{
   Animal()
   { 
      reg;  //force specialization
   }
   virtual std::string name() = 0;
   static bool reg;
   static bool init() 
   { 
      T t; 
      AnimalManager::registerAnimal(t.name());
      return true;
   }
};

template<class T>
bool Animal<T>::reg = Animal<T>::init();

struct Tiger : Animal<Tiger>
{
   virtual std::string name() { return "Tiger"; }
};
Run Code Online (Sandbox Code Playgroud)

在此代码中,只有Animal在专门化的情况下才能进行扩展.构造函数强制初始化static成员reg,然后调用register方法.

编辑:正如@David Hammen在评论中指出的那样,你将无法拥有一组Animal对象.但是,这可以通过使用模板继承的非模板类并将其用作基类来轻松解决,并且仅使用模板进行扩展.

  • 哇,这是一个很酷的伎俩.我一直在SO上学习新东西,+1. (2认同)

Lol*_*4t0 8

如果你坚持要注册每一只动物,为什么不做name一个Animal构造函数的参数.然后你可以把注册问题放到Animal构造函数中,每个派生都必须传递有效的名称和注册:

struct Animal
{
   Animal(std::string name){ AnimalManager::registerAnimal(name);}
}

struct Tiger : Animal
{
   Tiger():Animal("Tiger"){}
};
Run Code Online (Sandbox Code Playgroud)