Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have the convenient object factory template that creates objects by their type id names. The implementation is pretty obvious: ObjectFactory contains the map from std::string to object creator function. Then all objects to be created shall be registered in this factory.

I use the following macro to do that:

#define REGISTER_CLASS(className, interfaceName) 
   class className; 
   static RegisterClass<className, interfaceName> regInFactory##className; 
   class className : public interfaceName

where RegisterClass is

   template<class T, class I>
   struct RegisterClass
   {
      RegisterClass()
      {
         ObjectFactory<I>::GetInstance().Register<T>();
      }
   };

Usage

class IFoo
{
public:
   virtual Do() = 0;
   virtual ~IFoo() {}
}

REGISTER_CLASS(Foo, IFoo)
{
   virtual Do() { /* do something */ }
}

REGISTER_CLASS(Bar, IFoo)
{
   virtual Do() { /* do something else */ }
}

Classes are defined and registered in factory simultaneously.

The problem is that regInFactory... static objects are defined in .h files, so they will be added to every translation unit. The same object creator will be registered several times, and, more important, there will be a lot of redundant objects with static storage duration.

Is there any way to do such elegant registration (not to copy/paste class and interface names), but do not spread redundant static objects around the globe?

If a good solution needs some VC++ specific extensions (not conforming to C++ standard), I will be OK with that.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
110 views
Welcome To Ask or Share your Answers For Others

1 Answer

So you want to put variables definitions in header file? There is a portable way: static variables of template classes. So we get:

template <typename T, typename I>
struct AutoRegister: public I
{
    // a constructor which use ourRegisterer so that it is instantiated; 
    // problem catched by bocco
    AutoRegister() { &ourRegisterer; } 
private:
    static RegisterClass<T, I> ourRegisterer;
};

template <typename T, typename I>
RegisterClass<T, I> AutoRegister<T, I>::ourRegisterer;

class Foo: AutoRegister<Foo, IFoo>
{
public:
    virtual void Do();         
};

Note that I've kept the inheritance of IFoo non virtual. If there is any risk of inheriting from that class multiple times, it should be virtual.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...