How to design a simple C++ object factory? - c++

In my application, there are 10-20 classes that are instantiated once[*]. Here's an example:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
Instances of the classes are contained in one object:
class TheManager {
public:
virtual SomeManagerClass* someManagerClass() const;
virtual SomeOtherManager* someOtherManager() const;
/** More objects... up to 10-20 */
};
Currently TheManager uses the new operator in order to create objects.
My intention is to be able to replace, using plugins, the SomeManagerClass (or any other class) implementation with another one. In order to replace the implementation, 2 steps are needed:
Define a class DerivedSomeManagerClass, which inherits SomeManagerClass [plugin]
Create the new class (DerivedSomeManagerClass) instead of the default (SomeManagerClass) [application]
I guess I need some kind of object factory, but it should be fairly simple since there's always only one type to create (the default implementation or the user implementation).
Any idea about how to design a simple factory like I just described? Consider the fact that there might be more classes in the future, so it should be easy to extend.
[*] I don't care if it happens more than once.
Edit: Please note that there are more than two objects that are contained in TheManager.

Assuming a class (plugin1) which inherits from SomeManagerClass, you need a class hierarchy to build your types:
class factory
{
public:
virtual SomeManagerClass* create() = 0;
};
class plugin1_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin1(); }
};
Then you can assign those factories to a std::map, where they are bound to strings
std::map<string, factory*> factory_map;
...
factory_map["plugin1"] = new plugin1_factory();
Finally your TheManager just needs to know the name of the plugin (as string) and can return an object of type SomeManagerClass with just one line of code:
SomeManagerClass* obj = factory_map[plugin_name]->create();
EDIT: If you don't like to have one plugin factory class for each plugin, you could modify the previous pattern with this:
template <class plugin_type>
class plugin_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin_type(); }
};
factory_map["plugin1"] = new plugin_factory<plugin1>();
I think this is a much better solution. Moreover the 'plugin_factory' class could add itself to the 'factory_map' if you pass costructor the string.

I think there are two separate problems here.
One problem is: how does TheManager name the class that it has to create? It must keep some kind of pointer to "a way to create the class". Possible solutions are:
keeping a separate pointer for each kind of class, with a way to set it, but you already said that you don't like this as it violates the DRY principle
keeping some sort of table where the key is an enum or a string; in this case the setter is a single function with parameters (of course if the key is an enum you can use a vector instead of a map)
The other problem is: what is this "way to create a class"? Unfortunately we can't store pointers to constructors directly, but we can:
create, as others have pointed out, a factory for each class
just add a static "create" function for each class; if they keep a consistent signature, you can just use their pointers to functions
Templates can help in avoiding unnecessary code duplication in both cases.

I have answered in another SO question about C++ factories. Please see there if a flexible factory is of interest. I try to describe an old way from ET++ to use macros which has worked great for me.
ET++ was a project to port old MacApp to C++ and X11. In the effort of it Eric Gamma etc started to think about Design Patterns

I'd create a "base" factory that has virtual methods for creation of all the basic managers, and let the "meta manager" (TheManager in your question) take a pointer to the base factory as a constructor parameter.
I'm assuming that the "factory" can customize the instances of CXYZWManager by deriving from them, but alternatively the constructor of CXYZWManager could take different arguments in the "custom" factory.
A lengthy code example that outputs "CSomeManager" and "CDerivedFromSomeManager":
#include <iostream>
//--------------------------------------------------------------------------------
class CSomeManager
{
public:
virtual const char * ShoutOut() { return "CSomeManager";}
};
//--------------------------------------------------------------------------------
class COtherManager
{
};
//--------------------------------------------------------------------------------
class TheManagerFactory
{
public:
// Non-static, non-const to allow polymorphism-abuse
virtual CSomeManager *CreateSomeManager() { return new CSomeManager(); }
virtual COtherManager *CreateOtherManager() { return new COtherManager(); }
};
//--------------------------------------------------------------------------------
class CDerivedFromSomeManager : public CSomeManager
{
public:
virtual const char * ShoutOut() { return "CDerivedFromSomeManager";}
};
//--------------------------------------------------------------------------------
class TheCustomManagerFactory : public TheManagerFactory
{
public:
virtual CDerivedFromSomeManager *CreateSomeManager() { return new CDerivedFromSomeManager(); }
};
//--------------------------------------------------------------------------------
class CMetaManager
{
public:
CMetaManager(TheManagerFactory *ip_factory)
: mp_some_manager(ip_factory->CreateSomeManager()),
mp_other_manager(ip_factory->CreateOtherManager())
{}
CSomeManager *GetSomeManager() { return mp_some_manager; }
COtherManager *GetOtherManager() { return mp_other_manager; }
private:
CSomeManager *mp_some_manager;
COtherManager *mp_other_manager;
};
//--------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
TheManagerFactory standard_factory;
TheCustomManagerFactory custom_factory;
CMetaManager meta_manager_1(&standard_factory);
CMetaManager meta_manager_2(&custom_factory);
std::cout << meta_manager_1.GetSomeManager()->ShoutOut() << "\n";
std::cout << meta_manager_2.GetSomeManager()->ShoutOut() << "\n";
return 0;
}

Here's the solution I thought of, it's not the best one but maybe it will help to think of better solutions:
For each class there would be a creator class:
class SomeManagerClassCreator {
public:
virtual SomeManagerClass* create(SomeOtherManager* someOtherManager) {
return new SomeManagerClass(someOtherManager);
}
};
Then, the creators will be gathered in one class:
class SomeManagerClassCreator;
class SomeOtherManagerCreator;
class TheCreator {
public:
void setSomeManagerClassCreator(SomeManagerClassCreator*);
SomeManagerClassCreator* someManagerClassCreator() const;
void setSomeOtherManagerCreator(SomeOtherManagerCreator*);
SomeOtherManagerCreator* someOtherManagerCreator() const;
private:
SomeManagerClassCreator* m_someManagerClassCreator;
SomeOtherManagerCreator* m_someOtherManagerCreator;
};
And TheManager will be created with TheCreator for internal creation:
class TheManager {
public:
TheManager(TheCreator*);
/* Rest of code from above */
};
The problem with this solution is that it violates DRY - for each class creator I would have to write setter/getter in TheCreator.

This seems like it would be a lot simpler with function templating as opposed to an Abstract Factory pattern
class ManagerFactory
{
public:
template <typename T> static BaseManager * getManager() { return new T();}
};
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
If you want to get them via a string, you can create a standard map from strings to function pointers. Here is an implementation that works:
#include <map>
#include <string>
class BaseManager
{
public:
virtual void doSomething() = 0;
};
class DerivedManager1 : public BaseManager
{
public:
virtual void doSomething() {};
};
class DerivedManager2 : public BaseManager
{
public:
virtual void doSomething() {};
};
class ManagerFactory
{
public:
typedef BaseManager * (*GetFunction)();
typedef std::map<std::wstring, GetFunction> ManagerFunctionMap;
private:
static ManagerFunctionMap _managers;
public:
template <typename T> static BaseManager * getManager() { return new T();}
template <typename T> static void registerManager(const std::wstring& name)
{
_managers[name] = ManagerFactory::template getManager<T>;
}
static BaseManager * getManagerByName(const std::wstring& name)
{
if(_managers.count(name))
{
return _managers[name]();
}
return NULL;
}
};
// the static map needs to be initialized outside the class
ManagerFactory::ManagerFunctionMap ManagerFactory::_managers;
int _tmain(int argc, _TCHAR* argv[])
{
// you can get with the templated function
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
manager1->doSomething();
// or by registering with a string
ManagerFactory::template registerManager<DerivedManager1>(L"Derived1");
ManagerFactory::template registerManager<DerivedManager2>(L"Derived2");
// and getting them
BaseManager * manager2 = ManagerFactory::getManagerByName(L"Derived2");
manager2->doSomething();
BaseManager * manager3 = ManagerFactory::getManagerByName(L"Derived1");
manager3->doSomething();
return 0;
}
EDIT: In reading the other answers I realized that this is very similar to Dave Van den Eynde's FactorySystem solution, but I'm using a function template pointer instead of instantiating templated factory classes. I think my solution is a little more lightweight. Due to static functions, the only object that gets instantiated is the map itself. If you need the factory to perform other functions (DestroyManager, etc.), I think his solution is more extensible.

You could implement an object factory with static methods that return an instance of a Manager-Class. In the factory you could create a method for the default type of manager and a method for any type of manager which you give an argument representing the type of the Manager-Class (say with an enum). This last method should return an Interface rather than a Class.
Edit: I'll try to give some code, but mind that my C++ times are quite a while back and I'm doing only Java and some scripting for the time being.
class Manager { // aka Interface
public: virtual void someMethod() = 0;
};
class Manager1 : public Manager {
void someMethod() { return null; }
};
class Manager2 : public Manager {
void someMethod() { return null; }
};
enum ManagerTypes {
Manager1, Manager2
};
class ManagerFactory {
public static Manager* createManager(ManagerTypes type) {
Manager* result = null;
switch (type) {
case Manager1:
result = new Manager1();
break;
case Manager2:
result = new Manager2();
break;
default:
// Do whatever error logging you want
break;
}
return result;
}
};
Now you should be able to call the Factory via (if you've been able to make the code sample work):
Manager* manager = ManagerFactory.createManager(ManagerTypes.Manager1);

I would use templates like this as I can't see the point of factories classes:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
class TheBaseManager {
public:
//
};
template <class ManagerClassOne, class ManagerClassOther>
class SpecialManager : public TheBaseManager {
public:
virtual ManagerClassOne* someManagerClass() const;
virtual ManagerClassOther* someOtherManager() const;
};
TheBaseManager* ourManager = new SpecialManager<SomeManagerClass,SomeOtherManager>;

You should take a look at the tutorial at
http://downloads.sourceforge.net/papafactory/PapaFactory20080622.pdf?use_mirror=fastbull
It contains a great tutorial on implementing an Abstract factory in C++ and the source code that comes with it is also very robust
Chris

Mh I don't understand a hundred percent, and I am not really into factory stuff from books and articles.
If all your managers share a similar interface you could derive from a base class, and use this base class in your program.
Depending on where the decision which class will be created will be made, you have to use an identifier for creation (as stated above) or handle the decision which manager to instantiate internally.
Another way would be to implement it "policy" like by using templates. So that You ManagerClass::create() returns a specific SomeOtherManagerWhatever instance. This would lay the decision which manager to make in the code which uses your Manager - Maye this is not intended.
Or that way:
template<class MemoryManagment>
class MyAwesomeClass
{
MemoryManagment m_memoryManager;
};
(or something like that)
With this construct you can easily use other managers by only changing the instantiation of MyAwesomeClass.
Also A class for this purpose might be a little over the top. In your case a factory function would do I guess. Well it's more a question of personal preference.

If you plan on supporting plugins that are dynamically linked, your program will need to provide a stable ABI (Application Binary Interface), that means that you cannot use C++ as your main interface as C++ has no standard ABI.
If you want plugins to implement an interface you define yourself, you will have to provide the header file of the interface to plugin programmer and standardize on a very simple C interface in order to create and delete the object.
You cannot provide a dynamic library that will allow you to "new" the plugin class as-is. That is why you need to standardize on a C interface in order to create the object. Using the C++ object is then possible as long as none of your arguments use possibly incompatible types, like STL containers. You will not be able to use a vector returned by another library, because you cannot ensure that their STL implementation is the same as yours.
Manager.h
class Manager
{
public:
virtual void doSomething() = 0;
virtual int doSomethingElse() = 0;
}
extern "C" {
Manager* newManager();
void deleteManager(Manager*);
}
PluginManager.h
#include "Manager.h"
class PluginManager : public Manager
{
public:
PluginManager();
virtual ~PluginManager();
public:
virtual void doSomething();
virtual int doSomethingElse();
}
PluginManager.cpp
#include "PluginManager.h"
Manager* newManager()
{
return new PluginManager();
}
void deleteManager(Manager* pManager)
{
delete pManager;
}
PluginManager::PluginManager()
{
// ...
}
PluginManager::~PluginManager()
{
// ...
}
void PluginManager::doSomething()
{
// ...
}
int PluginManager::doSomethingElse()
{
// ...
}

You didnt talk about TheManager. It looks like you want that to control which class is being used? or maybe you trying to chain them together?
It sounds like you need a abstract base class and a pointer to the currently used class. If you wish to chain you can do it in both abstract class and themanager class. If abstract class, add a member to the next class in chain, if themanager then sort it in order you which to use in a list. You'll need a way to add classes so you'll need an addMe() in themanager. It sounds like you know what your doing so w/e you choose should be right. A list with an addMe func is my recommendation and if you want only 1 active class then a function in TheManager deciding it would be good.

This maybe heavier than you need, but it sounds like you are trying to make a frame work class that supports plugins.
I would break it up into to 3 sections.
1) The FrameWork class would own the plugins.
This class is responsable for publishing interfaces supplied by the plugins.
2) A PlugIn class would own the componets that do the work.
This class is responsable for registering the exported interfaces, and binding the imported interfaces to the components.
3) The third section, the componets are the suppliers and consumers of the interfaces.
To make things extensible, getting things up and running might be broke up into stages.
Create everything.
Wire everything up.
Start everything.
To break things down.
Stop everything.
Destroy everything.
class IFrameWork {
public:
virtual ~IFrameWork() {}
virtual void RegisterInterface( const char*, void* ) = 0;
virtual void* GetInterface( const char* name ) = 0;
};
class IPlugIn {
public:
virtual ~IPlugIn() {}
virtual void BindInterfaces( IFrameWork* frameWork ) {};
virtual void Start() {};
virtual void Stop() {};
};
struct SamplePlugin :public IPlugIn {
ILogger* logger;
Component1 component1;
WebServer webServer;
public:
SamplePlugin( IFrameWork* frameWork )
:logger( (ILogger*)frameWork->GetInterface( "ILogger" ) ), //assumes the 'System' plugin exposes this
component1(),
webServer( component1 )
{
logger->Log( "MyPlugin Ctor()" );
frameWork->RegisterInterface( "ICustomerManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IVendorManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IAccountingManager", dynamic_cast( &webServer ) );
}
virtual void BindInterfaces( IFrameWork* frameWork ) {
logger->Log( "MyPlugin BindInterfaces()" );
IProductManager* productManager( static_cast( frameWork->GetInterface( "IProductManager" ) ) );
IShippingManager* shippingManager( static_cast( frameWork->GetInterface( "IShippingManager" ) ) );
component1.BindInterfaces( logger, productManager );
webServer.BindInterfaces( logger, productManager, shippingManager );
}
virtual void Start() {
logger->Log( "MyPlugin Start()" );
webServer.Start();
}
virtual void Stop() {
logger->Log( "MyPlugin Stop()" );
webServer.Stop();
}
};
class FrameWork :public IFrameWork {
vector plugIns;
map interfaces;
public:
virtual void RegisterInterface( const char* name, void* itfc ) {
interfaces[ name ] = itfc;
}
virtual void* GetInterface( const char* name ) {
return interfaces[ name ];
}
FrameWork() {
//Only interfaces in 'SystemPlugin' can be used by all methods of the other plugins
plugIns.push_back( new SystemPlugin( this ) );
plugIns.push_back( new SamplePlugin( this ) );
//add other plugIns here
for_each( plugIns.begin(), plugIns.end(), bind2nd( mem_fun( &IPlugIn::BindInterfaces ), this ) );
for_each( plugIns.begin(), plugIns.end(), mem_fun( &IPlugIn::Start ) );
}
~FrameWork() {
for_each( plugIns.rbegin(), plugIns.rend(), mem_fun( &IPlugIn::Stop ) );
for_each( plugIns.rbegin(), plugIns.rend(), Delete() );
}
};

Here's a minimal factory pattern implementation that I came up with in about 15 minutes. We use a similar one that uses more advanced base classes.
#include "stdafx.h"
#include <map>
#include <string>
class BaseClass
{
public:
virtual ~BaseClass() { }
virtual void Test() = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class DerivedClass2 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class IFactory
{
public:
virtual BaseClass* CreateNew() const = 0;
};
template <typename T>
class Factory : public IFactory
{
public:
T* CreateNew() const { return new T(); }
};
class FactorySystem
{
private:
typedef std::map<std::wstring, IFactory*> FactoryMap;
FactoryMap m_factories;
public:
~FactorySystem()
{
FactoryMap::const_iterator map_item = m_factories.begin();
for (; map_item != m_factories.end(); ++map_item) delete map_item->second;
m_factories.clear();
}
template <typename T>
void AddFactory(const std::wstring& name)
{
delete m_factories[name]; // Delete previous one, if it exists.
m_factories[name] = new Factory<T>();
}
BaseClass* CreateNew(const std::wstring& name) const
{
FactoryMap::const_iterator found = m_factories.find(name);
if (found != m_factories.end())
return found->second->CreateNew();
else
return NULL; // or throw an exception, depending on how you want to handle it.
}
};
int _tmain(int argc, _TCHAR* argv[])
{
FactorySystem system;
system.AddFactory<DerivedClass1>(L"derived1");
system.AddFactory<DerivedClass2>(L"derived2");
BaseClass* b1 = system.CreateNew(L"derived1");
b1->Test();
delete b1;
BaseClass* b2 = system.CreateNew(L"derived2");
b2->Test();
delete b2;
return 0;
}
Just copy & paste over an initial Win32 console app in VS2005/2008. I like to point out something:
You don't need to create a concrete factory for every class. A template will do that for you.
I like to place the entire factory pattern in its own class, so that you don't need to worry about creating factory objects and deleting them. You simply register your classes, a factory class gets created by the compiler and a factory object gets created by the pattern. At the end of its lifetime, all factories are cleanly destroyed. I like this form of encapsulation, as there is no confusion over who governs the lifetime of the factories.

Related

Factory pattern with private constructors in C++

I am trying to implement a factory pattern that consists of
a factory class
an abstract class with protected constructor
inherited classes with private constructors and virtual public
destructors.
I want to make sure that
No other one than the factory can not create any instance
If a new inherited class is defined it will not require any modification on interface class and already defined inherited classes. Juts new class implementation and adding into factory classes create method.
I also do not want to write same-like code(like static factory method per inited) for every inherited class and leave the future developers much work for factory connections.
i.e with pseduo code
class Factory;
class Interface
{
protected:
Interface(){/*Do something*/};
public:
virtual ~Interface(){/*Do something*/}
/*I wish I could do below and it is valid for all inherited
classes but friendship is not inherited in C++*/
//friend Interface* Factory::create(Type)
};
class InheritedA:public Interface
{
private:
InheritedA(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
/*I dont want to do below two lines for every inherited class*/
//friend Interface Factory::create(Type)
//public: Interface* factoryInheritedA(){return new InheritedA();}
};
class InheritedB:public Interface
{
private:
InheritedB(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
};
class Factory
{
static Interface* create(Interface type)
{
switch(type)
{
case A:
return new InheritedA();
case B:
return new InheritedB();
default:
//exceptions etc
}
}
}
int main()
{
Interface* I = Factory::create(A/*or B*/);
return 0;
}
Above code is the cloest I put out. Any suggestions (a speciality of C++, a different design,...) is welcome.
I don't think this a good idea, but here is a way to do this. You create a Tag type which can only be created by the Factory and make all the constructors take a parameter of that type.
class Factory;
class Tag
{
Tag() {}
friend Factory;
};
class Interface
{
public:
Interface(Tag t) {}
virtual ~Interface() {}
};
struct Impl1: public Interface
{
Impl1(Tag t): Interface(t) {}
};
class Factory
{
public:
Interface* makeInstance()
{
return new Impl1( Tag{} );
}
};
void foo()
{
Impl1 i( Tag{} );
}
You will get a compiler error in foo() because Tag::Tag is private.
You could have a templated function:
template<typename Type>
std::unique_ptr<Interface> make_interface() {
// exceptions etc..
}
template<>
std::unique_ptr<Interface> make_interface<InheritedA>() {
return std::make_unique<InheritedA>();
}
template<>
std::unique_ptr<Interface> make_interface<InheritedB>() {
return std::make_unique<InheritedB>();
}
but I really don't see the point in all of this Javaesque boilerplate. Not to mention that you are transforming a compile time information (the type) into a runtime one (via exceptions) for no reason really.
I would just go with:
std::unique_ptr<Interface> ptr_a = std::make_unique<InheritedA>();
std::unique_ptr<Interface> ptr_b = std::make_unique<InheritedB>();
when needed.
It is rarely a good practice to use Factory. I count it as an anti-pattern together with the Singleton. In good design, classess do not concern themselves on how they are created. In your case, when used in Factory, how do you create your class using custom allocator? On stack? In shared memory? In memory-mapped file? From the buffer? In place? This is all really hard to cover in Factory, but do not despair - the simple and elegant solution is ditch the factory!

Am I Abusing Inheritance Here? What's A Best-Practice Alternative/Pattern?

BIG EDIT
So after gathering some feedback from all of you, and meditating on the XY problem as Zack suggested, I decided to add another code example which illustrates exactly what I'm trying to accomplish (ie the "X") instead of asking about my "Y".
So now we are working with cars and I've added 5 abstract classes: ICar, ICarFeatures, ICarParts, ICarMaker, ICarFixer. All of these interfaces will wrap or use a technology-specific complex object provided by a 3rd party library, depending on the derived class behind the interface. These interfaces will intelligently manage the life cycle of the complex library objects.
My use case here is the FordCar class. In this example, I used the Ford library to access classes FordFeatureImpl, FordPartsImpl, and FordCarImpl. Here is the code:
class ICar {
public:
ICar(void) {}
virtual ~ICar(void) {}
};
class FordCar : public ICar {
public:
ICar(void) {}
~FordCar(void) {}
FordCarImpl* _carImpl;
};
class ICarFeatures {
public:
ICarFeatures(void) {}
virtual ~ICarFeatures(void) {}
virtual void addFeature(UserInput feature) = 0;
};
class FordCarFeatures : public ICarFeatures{
public:
FordCarFeatures(void) {}
virtual ~FordCarFeatures(void) {}
virtual void addFeature(UserInput feature){
//extract useful information out of feature, ie:
std::string name = feature.name;
int value = feature.value;
_fordFeature->specialAddFeatureMethod(name, value);
}
FordFeatureImpl* _fordFeature;
};
class ICarParts {
public:
ICarParts(void) {}
virtual ~ICarParts(void) {}
virtual void addPart(UserInput part) = 0;
};
class FordCarParts :public ICarParts{
public:
FordCarParts(void) {}
virtual ~FordCarParts(void) {}
virtual void addPart(UserInput part) {
//extract useful information out of part, ie:
std::string name = part.name;
std::string dimensions = part.dimensions;
_fordParts->specialAddPartMethod(name, dimensions);
}
FordPartsImpl* _fordParts;
};
class ICarMaker {
public:
ICarMaker(void) {}
virtual ~ICarMaker(void) {}
virtual ICar* makeCar(ICarFeatures* features, ICarParts* parts) = 0;
};
class FordCarMaker {
public:
FordCarMaker(void) {}
virtual ~FordCarMaker(void) {}
virtual ICar* makeCar(ICarFeatures* features, ICarParts* parts){
FordFeatureImpl* fordFeatures = dynamic_cast<FordFeatureImpl*>(features);
FordPartsImpl* fordParts = dynamic_cast<FordPartsImpl*>(parts);
FordCar* fordCar = customFordMakerFunction(fordFeatures, fordParts);
return dynamic_cast<ICar*>(fordCar);
}
FordCar* customFordMakerFunction(FordFeatureImpl* fordFeatures, FordPartsImpl* fordParts) {
FordCar* fordCar = new FordCar;
fordCar->_carImpl->specialFeatureMethod(fordFeatures);
fordCar->_carImpl->specialPartsMethod(fordParts);
return fordCar;
}
};
class ICarFixer {
public:
ICarFixer(void) {}
virtual ~ICarFixer(void) {}
virtual void fixCar(ICar* car, ICarParts* parts) = 0;
};
class FordCarFixer {
public:
FordCarFixer(void) {}
virtual ~FordCarFixer(void) {}
virtual void fixCar(ICar* car, ICarParts* parts) {
FordCar* fordCar = dynamic_cast<FordCar*>(car);
FordPartsImpl* fordParts = dynamic_cast<FordPartsImpl*>(parts);
customFordFixerFunction(fordCar, fordParts);
}
customFordFixerFunction(FordCar* fordCar, FordPartsImpl* fordParts){
fordCar->_carImpl->specialRepairMethod(fordParts);
}
};
Notice that I must use dynamic casting to access the technology-specific objects within the abstract interfaces. This is what makes me think I'm abusing inheritance and provoked me to ask this question originally.
Here is my ultimate goal:
UserInput userInput = getUserInput(); //just a configuration file ie XML/YAML
CarType carType = userInput.getCarType();
ICarParts* carParts = CarPartFactory::makeFrom(carType);
carParts->addPart(userInput);
ICarFeatures* carFeatures = CarFeaturesFactory::makeFrom(carType);
carFeatures->addFeature(userInput);
ICarMaker* carMaker = CarMakerFactory::makeFrom(carType);
ICar* car = carMaker->makeCar(carFeatures, carParts);
UserInput repairSpecs = getUserInput();
ICarParts* replacementParts = CarPartFactory::makeFrom(carType);
replacementParts->addPart(repairSpecs);
ICarFixer* carFixer = CarFixerFactory::makeFrom(carType);
carFixer->fixCar(car, replacementParts);
Perhaps now you all have a better understanding of what I'm trying to do and perhaps where I can improve.
I'm trying to use pointers of base classes to represent derived (ie Ford) classes, but the derived classes contain specific objects (ie FordPartsImpl) which are required by the other derived classes (ie FordCarFixer needs a FordCar and FordPartsImpl object). This requires me to use dynamic casting to downcast a pointer from the base to its respective derived class so I can access these specific Ford objects.
My question is: am I abusing inheritance here? I'm trying to have a many-to-many relationship between the workers and objects. I feel like I'm doing something wrong by having an Object family of class which literally do nothing but hold data and making the ObjectWorker class have to dynamic_cast the object to access the insides.
That is not abusing inheritance... This is abusing inheritance
class CSNode:public CNode, public IMvcSubject, public CBaseLink,
public CBaseVarObserver,public CBaseDataExchange, public CBaseVarOwner
Of which those who have a C prefix have huge implementations
Not only that... the Header is over 300 lines of declarations.
So no... you are not abusing inheritance right now.
But this class I just showed you is the product of erosion. I'm sure the Node as it began it was a shinning beacon of light and polymorphism, able to switch smartly between behavior and nodes.
Now it has become a Kraken, a Megamoth, Cthulu itself trying to chew my insides with only a vision of it.
Heed this free man, heed my counsel, beware of what your polymorphism may become.
Otherwise it is fine, a fine use of inheritance of something I suppose is an Architecture in diapers.
What other alternatives do I have if I want to only have a single work() method?
Single Work Method... You could try:
Policy Based Design, where a policy has the implementation of your model
A Function "work" that it is used by every single class
A Functor! Instantiated in every class that it will be used
But your inheritance seems right, a single method that everyone will be using.
One more thing....I'm just gonna leave this wiki link right here
Or maybe just copy paste the wiki C++ code... which is very similar to yours:
#include <iostream>
#include <string>
template <typename OutputPolicy, typename LanguagePolicy>
class HelloWorld : private OutputPolicy, private LanguagePolicy
{
using OutputPolicy::print;
using LanguagePolicy::message;
public:
// Behaviour method
void run() const
{
// Two policy methods
print(message());
}
};
class OutputPolicyWriteToCout
{
protected:
template<typename MessageType>
void print(MessageType const &message) const
{
std::cout << message << std::endl;
}
};
class LanguagePolicyEnglish
{
protected:
std::string message() const
{
return "Hello, World!";
}
};
class LanguagePolicyGerman
{
protected:
std::string message() const
{
return "Hallo Welt!";
}
};
int main()
{
/* Example 1 */
typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyEnglish> HelloWorldEnglish;
HelloWorldEnglish hello_world;
hello_world.run(); // prints "Hello, World!"
/* Example 2
* Does the same, but uses another language policy */
typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyGerman> HelloWorldGerman;
HelloWorldGerman hello_world2;
hello_world2.run(); // prints "Hallo Welt!"
}
More important questions are
How are you going to use an Int Object with your StringWorker?
You current implementation won't be able to handle that
With policies it is possible.
What are the possible objects?
Helps you define if you need this kind of behavior
And remember, don't kill a chicken with a shotgun
Maybe your model will never really change overtime.
You have committed a design error, but it is not "abuse of inheritance". Your error is that you are trying to be too generic. Meditate upon the principle of You Aren't Gonna Need It. Then, think about what you actually have. You don't have Objects, you have Dogs, Cats, and Horses. Or perhaps you have Squares, Polygons, and Lines. Or TextInEnglish and TextInArabic. Or ... the point is, you probably have a relatively small number of concrete things and they probably all go in the same superordinate category. Similarly, you do not have Workers. On the assumption that what you have is Dogs, Cats, and Horses, then you probably also have an Exerciser and a Groomer and a Veterinarian.
Think about your concrete problem in concrete terms. Implement only the classes and only the relationships that you actually need.
The point is that you're not accessing the specific functionality through the interfaces. The whole reason for using interfaces is that you want all Cars to be made, fixed and featured ... If you're not going to use them in that way, don't use interfaces (and inheritance) at all, but simply check at user input time which car was chosen and instantiate the correct specialized objects.
I've changed your code a bit so that only at "car making" time there will be an upward dynamic_cast. I would have to know all the things you want to do exactly to create interfaces I would be really happy with.
class ICar {
public:
ICar(void) {}
virtual ~ICar(void) {}
virtual void specialFeatureMethod(ICarFeatures *specialFeatures);
virtual void specialPartsMethod(ICarParts *specialParts);
virtual void specialRepairMethod(ICarParts *specialParts);
};
class FordCar : public ICar {
public:
FordCar(void) {}
~FordCar(void) {}
void specialFeatureMethod(ICarFeatures *specialFeatures) {
//Access the specialFeatures through the interface
//Do your specific Ford stuff
}
void specialPartsMethod(ICarParts *specialParts) {
//Access the specialParts through the interface
//Do your specific Ford stuff
}
void specialRepairMethod(ICarParts *specialParts) {
//Access the specialParts through the interface
//Do your specific Ford stuff
}
};
class ICarFeatures {
public:
ICarFeatures(void) {}
virtual ~ICarFeatures(void) {}
virtual void addFeature(UserInput feature) = 0;
};
class FordCarFeatures : public ICarFeatures{
public:
FordCarFeatures(void) {}
~FordCarFeatures(void) {}
void addFeature(UserInput feature){
//extract useful information out of feature, ie:
std::string name = feature.name;
int value = feature.value;
_fordFeature->specialAddFeatureMethod(name, value);
}
FordFeatureImpl* _fordFeature;
};
class ICarParts {
public:
ICarParts(void) {}
virtual ~ICarParts(void) {}
virtual void addPart(UserInput part) = 0;
};
class FordCarParts :public ICarParts{
public:
FordCarParts(void) {}
~FordCarParts(void) {}
void addPart(UserInput part) {
//extract useful information out of part, ie:
std::string name = part.name;
std::string dimensions = part.dimensions;
_fordParts->specialAddPartMethod(name, dimensions);
}
FordPartsImpl* _fordParts;
};
class ICarMaker {
public:
ICarMaker(void) {}
virtual ~ICarMaker(void) {}
virtual ICar* makeCar(ICarFeatures* features, ICarParts* parts) = 0;
};
class FordCarMaker {
public:
FordCarMaker(void) {}
~FordCarMaker(void) {}
ICar* makeCar(ICarFeatures* features, ICarParts* parts){
return customFordMakerFunction(features, parts);
}
ICar* customFordMakerFunction(ICarFeatures* features, ICarParts* parts) {
FordCar* fordCar = new FordCar;
fordCar->specialFeatureMethod(features);
fordCar->specialPartsMethod(parts);
return dynamic_cast<ICar*>(fordCar);
}
};
class ICarFixer {
public:
ICarFixer(void) {}
virtual ~ICarFixer(void) {}
virtual void fixCar(ICar* car, ICarParts* parts) = 0;
};
class FordCarFixer {
public:
FordCarFixer(void) {}
~FordCarFixer(void) {}
void fixCar(ICar* car, ICarParts* parts) {
customFordFixerFunction(car, parts);
}
void customFordFixerFunction(ICar* fordCar, ICarParts *fordParts){
fordCar->specialRepairMethod(fordParts);
}
};
One can do better (for certain values of "better"), with increased complexity.
What is actually being done here? Let's look point by point:
There's some object type, unknown statically, determined at run time from a string
There's some worker type, also unknown statically, determined at run time from another string
Hopefully the object type and the worker type will match
We can try to turn "hopefully" into "certainly" with some template code.
ObjectWorkerDispatcher* owd =
myDispatcherFactory->create("someWorker", "someObject");
owd->dispatch();
Obviously both object and worker are hidden in the dispatcher, which is completely generic:
class ObjectWorkerDispatcher {
ObjectWorkerDispatcher(string objectType, string workerType) { ... }
virtual void dispatch() = 0;
}
template <typename ObjectType>
class ConcreteObjectWorkerDispatcher : public ObjectWorkerDispatcher {
void dispatch () {
ObjectFactory<ObjectType>* of = findObjectFactory(objectTypeString);
WorkerFactory<ObjectType>* wf = findWorkerFactory(workerTypeString);
ObjectType* obj = of->create();
Worker<ObjectType>* wrk = wf->create();
wrk->doWork(obj);
}
map<string, ObjectFactory<ObjectType>*> objectFactories;
map<string, WorkerFactory<ObjectType>*> workerFactories;
ObjectFactory<ObjectType>* findObjectFactory(string) { .. use map }
WorkerFactory<ObjectType>* findWorkerFactory(string) { .. use map }
}
We have different unrelated types of Object. No common Object class, but we can have e.g. several subtypes of StringObject, all compatible with all kinds of StringWorker.
We have an abstract Worker<ObjectType> class template and concrete MyStringWorker : public Worker<StringObject> , OtherStringWorker : public Worker<StringObject> ... classes.
Both kinds of factories are inheritance-free. Different types of factories are kept completely separate (in different dispatchers) and never mix.
There's still some amount of blanks to fill in, but hopefully it all should be more or less clear.
No casts are used in making of this design. You decide whether this property alone is worth such an increase in complexity.
I think you have the right solution per your needs. One thing I see that can be improved is removing the use of carType from the function that deals with the objects at the base class level.
ICar* FordCarFixer::getFixedCar(UserInput& userInput)
{
FordCarParts* carParts = new FordPartFactory;
carParts->addPart(userInput);
FordCarFeatures* carFeatures = new FordCarFeatures;
carFeatures->addFeature(userInput);
FordCarMaker* carMaker = new FordCarMaker;
FordCar* car = carMaker->makeCar(carFeatures, carParts);
UserInput repairSpecs = getUserInput();
ForCarParts* replacementParts = new ForCarParts;
replacementParts->addPart(repairSpecs);
FordCarFixer* carFixer = new FordCarFixer;
carFixer->fixCar(car, replacementParts);
return car;
}
UserInput userInput = getUserInput();
ICar* car = CarFixerFactory::getFixedCar(userInput);
With this approach, most of the objects at FordCarFixer level are Ford-specific.

How can 2 different classes point to the same datatable name

I need to initialize an object in a method without specifying the class from where the object is. Can I do that?
can someone give me an example?
EDIT:
MyClass{
...};
MySecondClass
{...
};
void method(*object); //how to write correct??
{..}
MyClass *x= new MyClass();
MySecondClass *y= new MySecondClass();
method(x);
method(y);
Use templates.
template <typename T>
void method(T* object) {
// do stuff with the object, whose real type will be substituted for `T`
}
Templates are a bit complex, so read the chapter in your C++ book on them for more information.
It sounds like you're looking for an interface. You would define an interface that fits the needs of whatever it is that your method is doing.
class MyInterface
{
public:
virtual void doSomething1() = 0;
virtual void doSomething2() = 0;
};
class MyObject : public MyInterface
{
public:
void doSomething1()
{
// Code here
}
void doSomething2()
{
// Code here
}
};
It's somewhat unclear exactly the situation you have b/c you haven't shown any code, but make the method you want to call part of a class. (if it isn't already)
class ClassWithMethod
{
public:
ClassWithMethod(MyInterface &myI)
:x(myI)
{
}
void methodYouUseInjectedObject()
{
// Code
x.doSomething1();
// More code
}
private:
MyInterface &x;
};
Then in you application code where you instantiate the ClassWithMethod, you would "inject" the concrete type of the object you want called.
int main(int argc, char *argv[])
{
MyObject myObject;
ClassWithMethod classMethod(myObject);
// Call the method that will use the injected object.
classMethod.methodYouUseInjectedObject();
return 1;
}
EDIT: (based on updated question)
If you want to create a method that can take two different (and unrelated) objects, but the use the same method signatures you can use a template.
class ClassWithMethod
{
public:
template <class T>
void methodYouUseInjectedObject(T object)
{
T.doSomething();
}
};
This is similar to my approach above except that you do not need to derive your different objects off an interface.
You can use a template.
template<typename T>
void method(T object) {
object.doSomething()
}

minimal reflection in C++

I want to create a class factory and I would like to use reflection for that. I just need to
create a object with given string and invoke only few known methods.
How i can do that?
You will have to roll your own. Usually you have a map of strings to object creation functions.
You will need something like the follwing:
class thing {...};
/*
class thing_A : public thing {...};
class thing_B : public thing {...};
class thing_C : public thing {...};
*/
std::shared_ptr<thing> create_thing_A();
std::shared_ptr<thing> create_thing_C();
std::shared_ptr<thing> create_thing_D();
namespace {
typedef std::shared_ptr<thing> (*create_func)();
typedef std::map<std::string,create_func> creation_map;
typedef creation_map::value_type creation_map_entry;
const creation_map_entry creation_map_entries[] = { {"A", create_thing_A}
, {"B", create_thing_B}
, {"C", create_thing_C} };
const creation_map creation_funcs(
creation_map_entries,
creation_map_entries + sizeof(creation_map_entries)
/ sizeof(creation_map_entries[0] );
}
std::shared_ptr<thing> create_thing(const std::string& type)
{
const creation_ma::const_iterator it = creation_map.find(type);
if( it == creation_map.end() ) {
throw "Dooh!"; // or return NULL or whatever suits you
}
return it->second();
}
There are other ways to do this (like having a map of strings to objects from which to clone), but I think they all boil down to having a map of strings to something related to the specific types.
There is no reflection in C++, directly supported by the standard.
However C++ is sufficiently low-level that you can implement some minimal support for reflection to complete the task at hand.
For the simple task of creating a Factory, you usually use the Prototype approach:
class Base
{
public:
virtual Base* clone() const = 0;
virtual ~Base();
};
class Factory
{
public:
std::unique_ptr<Base> get(std::string const& name);
void set(std::string const& name, std::unique_ptr<Base> b);
private:
boost::ptr_map<std::string,Base> mExemplars;
};
Of course, those "known methods" that you are speaking about should be defined within the Base class, which acts as an interface.
There is no reflection in C++, so you should restate your question trying to explain what are the requirements that you would have fulfilled with the reflection part of it.
Depending on your actual constraints and requirements, there are a few things that you can do. The first approach that I would take would be creating an abstract factory where concrete factories can register and provide a simple interface:
class Base {}; // shared base by all created objects
class ConcreteFactoryBase {
public:
virtual ~ConcreteFactoryBase() {}
virtual Base* create() const = 0; // actual construction
virtual std::string id() const = 0; // id of the types returned
};
class AbstractFactory
{
typedef std::map<std::string, ConcreteFactory* > factory_map_t;
public:
void registerFactory( ConcreteFactoryBase* factory ) {
factories[ factory->id() ] = factory;
}
Base* create( std::string const & id ) const {
factory_map_t::const_iterator it = factories.find( id );
if ( it == factories.end() ) {
return 0; // or throw, or whatever makes sense in your case
}
return (*it)->create();
}
~AbstractFactory(); // ensure that the concrete factories are deleted
private:
std::map<ConcreteFactoryBase*> factories;
};
The actual concrete factories can be implemented manually but they can probably be templated, unless the constructors for the different types require different arguments:
template <typename T>
class ConcreteFactory : public ConcreteFactoryBase {
public:
ConcreteFactory( std::string const & id ) : myid(id) {}
virtual Base* create() const {
return new T;
}
virtual std::string id() const {
return myid;
}
private:
std::string myid;
};
class Test : public Base {};
int main() {
AbstracFactory factory;
factory.register_factory( new ConcreteFactory<Test>("Test") );
}
Optionally you could adapt the signatures so that you can pass arguments to the constructor through the different layers.
Then again, by knowing the actual constraints some other approaches might be better. The clone() approach suggested elsewhere is good (either by actually cloning or by creating an empty object of the same type). That is basically blending the factory with the objects themselves so that each object is a factory of objects of the same type. I don't quite like mixing those two responsabilities but it might be one of the simplest approaches with less code to write.
You could use typeid & templates to implement the factory so you won't need strings at all.
#include <string>
#include <map>
#include <typeinfo>
//***** Base *****
class Base
{
public:
virtual ~Base(){} //needs to be virtual to make typeid work
};
//***** C1 *****
class C1 : public Base
{};
//***** Factory *****
class Factory
{
public:
template <class T>
Base& get();
private:
typedef std::map<std::string, Base> BaseMap;
BaseMap m_Instances;
};
template <class T>
Base& Factory::get()
{
BaseMap::const_iterator i = m_Instances.find(typeid(T).name());
if(i == m_Instances.end()) {
m_Instances[typeid(T).name()] = T();
}
return m_Instances[typeid(T).name()];
}
//***** main *****
int main(int argc, char *argv[])
{
Factory f;
Base& c1 = f.get<C1>();
return 0;
}

Looking for a better C++ class factory

I have an application that has several objects (about 50 so far, but growing). There is only one instance of each of these objects in the app and these instances get shared among components.
What I've done is derive all of the objects from a base BrokeredObject class:
class BrokeredObject
{
virtual int GetInterfaceId() = 0;
};
And each object type returns a unique ID. These IDs are maintained in a header file.
I then have an ObjectBroker "factory". When someone needs an object, then call GetObjectByID(). The boker looks in an STL list to see if the object already exists, if it does, it returns it. If not, it creates it, puts it in the list and returns it. All well and good.
BrokeredObject *GetObjectByID(int id)
{
BrokeredObject *pObject;
ObjectMap::iterator = m_objectList.find(id);
// etc.
if(found) return pObject;
// not found, so create
switch(id)
{
case 0: pObject = new TypeA; break;
case 1: pObject = new TypeB; break;
// etc.
// I loathe this list
}
// add it to the list
return pObject;
}
What I find painful is maintaining this list of IDs and having to have each class implement it. I have at least made my consumer's lives slightly easier by having each type hold info about it's own ID like this:
class TypeA : public BrokeredObject
{
static int get_InterfaceID() { return IID_TYPEA; }
int GetInterfaceID() { return get_InterfaceID(); }
};
So I can get an object like this:
GetObjectByID(TypeA::get_InterfaceID());
Intead of having to actually know what the ID mapping is but I still am not thrilled with the maintenance and the potential for errors. It seems that if I know the type, why should I also have to know the ID?
What I long for is something like this in C#:
BrokeredObject GetOrCreateObject<T>() where T : BrokeredObject
{
return new T();
}
Where the ObjectBroker would create the object based on the type passed in.
Has C# spoiled me and it's just a fact of life that C++ can't do this or is there a way to achieve this that I'm not seeing?
Yes, there is a way. A pretty simple even in C++ to what that C# code does (without checking for inheritance though):
template<typename T>
BrokeredObject * GetOrCreateObject() {
return new T();
}
This will work and do the same as the C# code. It is also type-safe: If the type you pass is not inherited from BrokeredObject (or isn't that type itself), then the compiler moans at the return statement. It will however always return a new object.
Singleton
As another guy suggested (credits to him), this all looks very much like a fine case for the singleton pattern. Just do TypeA::getInstance() to get the one and single instance stored in a static variable of that class. I suppose that would be far easier than the above way, without the need for IDs to solve it (i previously showed a way using templates to store IDs in this answer, but i found it effectively is just what a singleton is).
I've read that you will leave the chance open to have multiple instances of the classes. One way to do that is to have a Mingleton (i made up that word :))
enum MingletonKind {
SINGLETON,
MULTITON
};
// Singleton
template<typename D, MingletonKind>
struct Mingleton {
static boost::shared_ptr<D> getOrCreate() {
static D d;
return boost::shared_ptr<D>(&d, NoopDel());
}
struct NoopDel {
void operator()(D const*) const { /* do nothing */ }
};
};
// Multiton
template<typename D>
struct Mingleton<D, MULTITON> {
static boost::shared_ptr<D> getOrCreate() {
return boost::shared_ptr<D>(new D);
}
};
class ImASingle : public Mingleton<ImASingle, SINGLETON> {
public:
void testCall() { }
// Indeed, we have to have a private constructor to prevent
// others to create instances of us.
private:
ImASingle() { /* ... */ }
friend class Mingleton<ImASingle, SINGLETON>;
};
class ImAMulti : public Mingleton<ImAMulti, MULTITON> {
public:
void testCall() { }
// ...
};
int main() {
// both do what we expect.
ImAMulti::getOrCreate()->testCall();
ImASingle::getOrCreate()->testCall();
}
Now, you just use SomeClass::getOrCreate() and it cares about the details. The custom deleter in the singleton case for shared_ptr makes deletion a no-op, because the object owned by the shared_ptr is allocated statically. However, be aware of problems of destruction order of static variables: Static initialization order fiasco
The way I would solve this problem is using what I would call the Static Registry Pattern, which in my mine mind is the C++ version of dependency injection.
Basically you have a static list of builder objects of a type that you use to build objects of another type.
A basic static registry implementation would look like:
template <class T>
class StaticRegistry
{
public:
typedef std::list<T*> Container;
static StaticRegistry<T>& GetInstance()
{
if (Instance == 0)
{
Instance = new StaticRegistry<T>;
}
return *Instance;
}
void Register(T* item)
{
Items.push_back(item);
}
void Deregister(T* item)
{
Items.remove(item);
if (Items.empty())
{
delete this;
Instance = 0;
}
}
typedef typename Container::const_iterator const_iterator;
const_iterator begin() const
{
return Items.begin();
}
const_iterator end() const
{
return Items.end();
}
protected:
StaticRegistry() {}
~StaticRegistry() {}
private:
Container Items;
static StaticRegistry<T>* Instance;
};
template <class T>
StaticRegistry<T>* StaticRegistry<T>::Instance = 0;
An implementation of BrokeredObjectBuilder could look like this:
class BrokeredObjectBuilderBase {
public:
BrokeredObjectBuilderBase() { StaticRegistry<BrokeredObjectBuilderBase>::GetInstance().Register(this); }
virtual ~BrokeredObjectBuilderBase() { StaticRegistry<BrokeredObjectBuilderBase>::GetInstance().Deregister(this); }
virtual int GetInterfaceId() = 0;
virtual BrokeredObject* MakeBrokeredObject() = 0;
};
template<class T>
class BrokeredObjectBuilder : public BrokeredObjectBuilderBase {
public:
BrokeredObjectBuilder(unsigned long interface_id) : m_InterfaceId(interface_id) { }
virtual int GetInterfaceId() { return m_InterfaceId; }
virtual T* MakeBrokeredObject() { return new T; }
private:
unsigned long m_InterfaceId;
};
class TypeA : public BrokeredObject
{
...
};
// Create a global variable for the builder of TypeA so that it's
// included in the BrokeredObjectBuilderRegistry
BrokeredObjectBuilder<TypeA> TypeABuilder(TypeAUserInterfaceId);
typedef StaticRegistry<BrokeredObjectBuilderBase> BrokeredObjectBuilderRegistry;
BrokeredObject *GetObjectByID(int id)
{
BrokeredObject *pObject(0);
ObjectMap::iterator = m_objectList.find(id);
// etc.
if(found) return pObject;
// not found, so create
BrokeredObjectBuilderRegistry& registry(BrokeredObjectBuilderRegistry::GetInstance());
for(BrokeredObjectBuilderRegistry::const_iterator it = registry.begin(), e = registry.end(); it != e; ++it)
{
if(it->GetInterfaceId() == id)
{
pObject = it->MakeBrokeredObject();
break;
}
}
if(0 == pObject)
{
// userinterface id not found, handle this here
...
}
// add it to the list
return pObject;
}
Pros:
All the code that knows about creating the types is seperated out into the builders and the BrokeredObject classes don't need to know about it.
This implementation can be used in libraries and you can control on a per project level what builders are pulled into a project using a number of different techniques.
The builders can be as complex or as simple (like above) as you want them to be.
Cons:
There is a wee bit of infrastructure involved (but not too much).
The flexability of defining the global variables to include what builders to include in your project does make it a little messy to work with.
I find that people find it hard to understand this pattern, I'm not sure why.
It's sometimes not easy to know what is in the static registry at any one time.
The above implementation leaks one bit of memory. (I can live with that...)
The above implementation is very simple, you can extend it in lots of different ways depending on the requirements you have.
Use a template class as the broker.
Make the instance a static member of the function. It will be created on first use and automagically-destroyed when the program exits.
template <class Type>
class BrokeredObject
{
public:
static Type& getInstance()
{
static Type theInstance;
return theInstance;
}
};
class TestObject
{
public:
TestObject()
{}
};
int main()
{
TestObject& obj =BrokeredObject<TestObject>::getInstance();
}
Instead of GetInterfaceId() in the BrokeredObject base class, you could define that pure virtual method:
virtual BrokeredObject& GetInstance()=0;
And in the derived classes you'll return from that method the instance of the particular derived class, if it's already created, if not, you'll first create it and then return it.
It doesn't look like you need the global object to do the management, so why not move everything into the classes themselves?
template <class Type>
class BrokeredObject
{
protected:
static Type *theInstance;
public:
static Type *getOrCreate()
{
if (!theInstance) {
theInstance = new Type();
}
return theInstance;
}
static void free()
{
delete theInstance;
}
};
class TestObject : public BrokeredObject<TestObject>
{
public:
TestObject()
{}
};
int
main()
{
TestObject *obj = TestObject::getOrCreate();
}
If you have RTTI enabled, you can get the class name using typeid.
One question, why are you using a factory rather than using a singleton pattern for each class?
Edit: OK, so you don't want to be locked into a singleton; no problem. The wonderful thing about C++ is it gives you so much flexibility. You could have a GetSharedInstance() member function that returns a static instance of the class, but leave the constructor public so that you can still create other instances.
If you always know the type at compile time there is little point in calling BrokeredObject* p = GetObjectByID(TypeA::get_InterfaceID()) instead of TypeA* p = new TypeA or TypeA o directly.
If you on the other hand don't know the exact type at compile time, you could use some kind of type registry.
template <class T>
BrokeredObject* CreateObject()
{
return new T();
}
typedef int type_identity;
typedef std::map<type_identity, BrokeredObject* (*)()> registry;
registry r;
class TypeA : public BrokeredObject
{
public:
static const type_identity identity;
};
class TypeB : public BrokeredObject
{
public:
static const type_identity identity;
};
r[TypeA::identity] = &CreateObject<TypeA>;
r[TypeB::identity] = &CreateObject<TypeB>;
or if you have RTTI enabled you could use type_info as type_identity:
typedef const type_info* type_identity;
typedef std::map<type_identity, BrokeredObject* (*)()> registry;
registry r;
r[&typeid(TypeA)] = &CreateObject<TypeA>;
r[&typeid(TypeB)] = &CreateObject<TypeB>;
Each new class could of course, in any case, be self-registering in the registry, making the registration decentralized instead of centralized.
You should almost certainly be using dependency injection.
Why not this?
template
BrokeredObject* GetOrCreateObject()
{
return new T();
}
My use-case tended to get a little more complex - I needed the ability to do a little bit of object initialization and I needed to be able to load objects from different DLLs based on configuration (e.g. simulated versus actual for hardware). It started looking like COM and ATL was where I was headed, but I didn't want to add the weight of COM to the OS (this is being done in CE).
What I ended up going with was template-based (thanks litb for putting me on track) and looks like this:
class INewTransModule
{
public:
virtual bool Init() { return true; }
virtual bool Shutdown() { return true; }
};
template <typename T>
struct BrokeredObject
{
public:
inline static T* GetInstance()
{
static T t;
return &t;
}
};
template <>
struct BrokeredObject<INewTransModule>
{
public:
inline static INewTransModule* GetInstance()
{
static INewTransModule t;
// do stuff after creation
ASSERT(t.Init());
return &t;
}
};
class OBJECTBROKER_API ObjectBroker
{
public:
// these calls do configuration-based creations
static ITraceTool *GetTraceTool();
static IEeprom *GetEeprom();
// etc
};
Then to ensure that the objects (since they're templated) actually get compiled I added definitions like these:
class EepromImpl: public BrokeredObject<EepromImpl>, public CEeprom
{
};
class SimEepromImpl: public BrokeredObject<SimEepromImpl>, public CSimEeprom
{
};