How to automatically register a class on creation

I was wondering whether a design pattern or idiom exists to automatically register a class type. Or simpler, can I force a method to get called on a class by simply extending a base class?

For example, say I have a base class Animal and extending classes Tiger and Dog, and I have a helper function that prints out all classes that extend Animal.

So I could have something like:

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

So basically I would do:

Tiger t;
t.registerAnimal();

This could be worked into a static function as well. Is there any pattern (like a curiously recursive template) or something like that that can help me achieve this without explicitly having to call the registerAnimal method.

I want my class Animal to be extendible in the future and others might forget to call register, I'm looking for ways to prevent that besides documenting this (which I will anyway).

PS This is just an example, I'm not actually implementing animals.


You can indeed do this using the curiously recursive template idiom. It requires nothing from whoever is extending the class that can't be enforced by the compiler:

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

In this code, you can only extend Animal if you specialize it. The constructor forces the static member reg to be initialized, which in turn calls the register method.

EDIT: As pointed out by @David Hammen in the comments, you won't be able to have a collection of Animal objects. However, this can easily be solved by having a non-template class from which the template inherits and use that as a base class, and only use the template for extending.


If you insist every animal should be registered, why not just make name a parameter of Animal constructor. Then you can put register issues to Animal constructor and every derived will have to pass valid name and register:

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

struct Tiger : Animal
{
   Tiger():Animal("Tiger"){}
};

This is a typical example where you want to do some sort of bookkeeping when an object is constructed. Item 9 in Scott Meyers "Effective C++" gives an example of this.

Basically you move all the bookkeeping stuff to base class. Derived class explicitly constructs base class and passes the information that is required for Base class construction. For example:

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

struct Dog : public Animal
{
  Dog() : Animal(animal_type()) {};


  private:      
    static std::string animal_type()
    {
      return "Dog";
    };
};

Usually I do this with a macro.

Unit test frameworks often employ the technique for registering the tests, e.g. GoogleTest