Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 918
AMCoder Avatar asked Apr 26 '12 11:04

AMCoder


People also ask

What is Register () in Python?

The register function simply returns its internal function, which in turn is executed immediately with the wrapped class type as its input. The internal function is the one that actually registers the class, and then returns the class type that will be added to the current namespace by the python interpreter.

Can a class have itself as a member?

// A class cannot have non-static object(s) of self type. If a non-static object is member then declaration of class is incomplete and compiler has no way to find out size of the objects of the class.

What is registering a class in Python?

Class registration is a helpful pattern for building modular Python programs. Metaclasses let you run registration code automatically each time your base class is subclassed in a program. Using metaclasses for class registration avoids errors by ensuring that you never miss a registration call.


1 Answers

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.

like image 174
Luchian Grigore Avatar answered Oct 14 '22 16:10

Luchian Grigore