Note that there are some explanatory texts on larger screens.

plurals
  1. POSingletons and factories with multiple libraries in C++
    primarykey
    data
    text
    <p>I've been reading and searching the web for a while now but haven't found a nice solution. Here's what I want to do:</p> <p>I am writing a library that defines an abstract base class - lets call it <strong>IFoo</strong>.</p> <pre><code>class IFoo { public: virtual void doSomething() = 0; virtual ~IFoo() {} }; </code></pre> <p>The library also defines a couple of implementations for that - lets call them <strong>FooLibOne</strong> and <strong>FooLibTwo</strong>.</p> <p>In order to encapsulate the creation process and decide which concrete implementation is used depending on some runtime paramter, I use a factory <strong>FooFactory</strong> that maps std::string to factory methods (in my case boost::function, but that should not be the point here). It also allows new factory methods to be registered. It looks something like this:</p> <pre><code>class FooFactory { public: typedef boost::function&lt;IFoo* ()&gt; CreatorFunction; IFoo* create(std::string name); void registerCreator(std::string name, CreatorFunction f); private: std::map&lt;std::string, CreatorFunction&gt; mapping_; }; </code></pre> <p>For now, I added the implementations provided (FooLibOne, FooLibTwo) by the library directly in the constructor of <strong>FooFactory</strong> - thus they are always available. Some of the library code uses the FooFactory to initialize certain objects etc. I have refrained from using the Singleton pattern for the factories so far since tee pattern is debated often enough and I wasn't sure, how different implementations of the Singleton pattern would work in combination with possibly multiple shared libraries etc. </p> <p>However, passing around the factories can be a little cumbersome and I still think, this is one of the occassions the Singleton pattern could be of good use. Especially if I consider, that the users of the library should be able to add more implementations of <strong>IFoo</strong> which should also be accessible for the (already existing) library code. Of course, Dependency Injection - meaning I pass an instance of a factory through the constructor - could do the trick (and does it for now). But this approach kind of fails if I want to be even more flexible and introduce a second layer of dynamic object creation. Meaning: I want to dynamicly create objects (see above) within dynamically created objects (say implementations of an abstract base class <strong>IBar</strong> - <strong>BarOne</strong> and <strong>BarTwo</strong> - again via a factory <strong>BarFactory</strong>).</p> <p>Lets say <strong>BarOne</strong> requires an <strong>IFoo</strong> object but <strong>BarTwo</strong> doesn't. I still have to provide the <strong>FooFactory</strong> to the <strong>BarFactory</strong> in any case, since one of the <strong>IBar</strong> implementations <em>might</em> need it. Having globally accessible factories would mitigate this problem and I wouldn't be forced to forsee, which factories may be needed by implementations of a specific interface. In addition I could register the creation methods directly in the source file of the implementations.</p> <pre><code>FooFactory::Instance().registerCreator("new_creator", boost::bind(...)); </code></pre> <p>Since I think it is a good idea, what would be the right way to implement it? I was going for a templated approach like the <strong>SingletonHolder</strong> from <em>Modern C++ Design</em> (see also <a href="http://loki-lib.sourceforge.net/" rel="nofollow">Loki</a> library) to wrap the factories. However, I'd rather implement it as a Meyer's Singleton instead. But I still think there will be issues with shared libraries. The solution should work with GCC (and preferably MSVC). I'm also open for other ideas from a design point of view but please avoid the common "Singletons are evil"-rants. ;-)</p> <p>Thanks in advance.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload