Generic factory in C++ [duplicate] - c++

This question already has answers here:
Is there a way to instantiate objects from a string holding their class name?
(12 answers)
Closed 8 years ago.
I'm working on a game and am trying to implement a smart way to create npc-objects in C++ from parsing a text file.
Currently this is hard coded in a Factory-object. Like this:
IActor * ActorFactory::create(string actortype, Room * r, string name, int hp)
{
if(actortype == "Troll")
{
return new Troll(r, name, hp);
}
if (actortype == "Dragon")
{
return new Dragon(r, name, hp);
}
// ... and so on
throw "Can't recognize type '"+actortype+"'.";
}
This is in my opinion a very ugly way to do it. Since it (among other things) breaks the Open/Closed principle.
I am schooled in Java, and in Java I would do something like having each IActor report it's class name and class type to the ActorFactory in the beginning of program execution. The factory would then store the relation in a map and can then easily look up what string maps to which object and it can then easily instantiate it.
Edit: I would also like to have the ability to call the constructor with a variable number/type of arguments.
How would this be done in C++? Can it be done?

In C++, you would typically use the Abstract Factory design pattern.
The point is: "the decision about the type of actor to create should not be the responsibility of ActorFactory::create()." In your case, this method should not decide which class to instantiate based on a string but would rather rely on a type; this type is the actual factory class.
Each actor class has its own factory class: TrollFactory, DragonFactory, etc. deriving from a base class ActorFactory2 (trailing 2 because ActoryFactory is already taken);
Each specialized factory class implements a virtual create() method without parameter returning a pointer to a newly created actor class;
If you need parameters to construct an actor, pass them to the factory object before creating the actor: pass them in the ctor and store them as member variables; create() will retrieve them later upon creation of the actor;
This way, you can easily pass different arguments for different actors and your factory mechanism will be scalable (a step toward the Open/Closed principle);
Now, ActorFactory::create() accepts a pointer to an object deriving from ActorFactory2 and calls the ActorFactory2::create() method: it will create the requested actor with appropriate arguments without switch statement.
class ActorFactory2
{
string m_name; // Each IA actor has a name
int m_hp; // and some HP
public:
ActorFactory2( const string &p_name, int p_hp )
: m_name( p_name ), m_hp( p_hp ) {}
virtual IActor * create() const = 0;
};
class TrollFactory : public ActorFactory2
{
// No special argument needed for Troll
public:
TrollFactory( const string &p_name, int p_hp )
: ActorFactory2( p_name, p_hp ) {}
virtual IActor * create() const { return new Troll( m_name, m_hp ); }
};
class DragonFactory : public ActorFactory2
{
FlameType m_flame; // Need to indicate type of flame a dragon spits
public:
DragonFactory( const string &p_name, int p_hp, const FlameType &p_flame )
: ActorFactory2( p_name, p_hp )
, m_flame( p_flame ) {}
virtual IActor * create() const { return new Dragon( m_name, m_hp, m_flame ); }
};
IActor * ActorFactory::create( const ActorFactory2 *factory )
{
return factory->create();
}
int main( int, char ** )
{
ActorFactory af;
...
// Create a dragon with a factory class instead of a string
ActorFactory2 *dragonFactory = new DragonFactory( "Fred", 100, RedFlames );
IActor *actor = af.create( dragonFactory ); // Instead of af.create( "dragon", ... )
delete dragonFactory;
}

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

The specific term is: parameterized factory method and it is part of the factory method design pattern.
To use a generic factory, hold the classes in a map and access via a string. If your class names are usable, register the class to the factory with "typeid(MyClass).name() and return a copy of the class by providing a clone() member function.
However, for simple not to extensible factories, I use the approach from your question.
I can't answer your question about passing more variable parameters, but to deserialize, it is enough to pass the portion to the class and let it deserialize itself (as you already seem to do).

You could use a map to store function pointers that'd return Actor*, with that being a pointer to the object being created. so then the code would just be
std::map<std::string,IActor* (*) (Room*,std::string,int)> constructorMap
constructorMap["Troll"]=&TrollConstructor
//etc...
IACtor* ActorFactory::create(string actortype,Room* r,string name,int hp){
return (*constructorMap[actortype])(r,name,hp);
}
(please excuse any possible screw-ups I made with the function pointers, they are not my strong point)

Related

OO Design -- where to put non-member functions

I have a class with a complex construction process with many parameters. Multiple clients share objects of this class, and the union of these clients parameters are used to instantiate the class. Therefore I have a factory class that stores these requirements, checks consistency of the various clients' requests, and instantiates the class.
Additionally, there are a common set of use models (or sets of parameters) which multiple clients use for multiple factories.
For instance, consider an example. (Note that the actual code is C++, but my experience is in Python so I'll pseudo-code in Python. Yes, I know that this example wouldn't actually work as-is.)
class Classroom:
def __init__(self, room_size=None, n_desks=None, n_boards=None,
n_books=None, has_globe=False, ... ):
...
class ClassroomFactory:
def __init__(self):
self._requirements = dict()
def addRequirement(self, name, value):
if name.startswith("n_"):
self._requirements[name] = max(value, self._requirements.get(name, 0))
...
def createClassroom(self):
return Classroom(**self._requirements)
# instantiate the factory
factory = ClassroomFactory()
# "client 1" is a geography teaacher
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
factory.addRequirement("has_globe", True)
# "client 2" is a math teacher
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
# "client 3" is a after-school day-care
factory.addRequirement("room_size", (20,20))
factory.addRequirement("has_carpet", True)
room = factory.createClassroom()
The common use model is as a teacher, we need 10 desks and a board. I think this is best served by a non-member function/decorator, something like:
def makeTeacherRoom(factory):
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
return factory
This seems like a great example of the "prefer non-member/non-friend to member" paradigm.
The thing that I'm struggling with is, within the framework of a much bigger OO code, where should these types of non-member functions/decorators live, both in terms of namespace and in terms of actual file?
Should they live in the factory's file/namespace? They are closely related to the factory, but they're limitations on the general factory, and need not be used to use the factory.
Should they live in the client's file/namespace? The client understands these use models, but this would limit re-use amongst multiple clients.
Should they live with a common base class of the clients (for instance, one could imagine a "teacher" class/namespace which would also provide the non-member function makeTeacherRoom(), which would be inherited by MathTeacher and GeographyTeacher.
Should they live somewhere else completely, in a "utils" file? And if so in which namespace?
This is primarily a personal decision. Most of your options have no technical negative effects. For example:
They could, because of locality of use, but it's not necessary.
They could, because of locality of data, but again...
They could, although this one does seem like it could make things a bit messier. Making utility classes, you may have to end up inheriting them, or making parts virtual to override later, which will get ugly pretty quick.
This is my personal favorite, or a variant of this.
I typically make a relevantly-named util file (or class with static methods) and put it in the same namespace as the classes it utilates (the more helpful version of mutilate). For a Education::Teacher class, you could have a Education::TeacherUtils file or class containing the functions that operate on Teacher. This keeps a pretty obvious naming tie-in, but also puts the util functions in their own area, so they can be included from whatever needs them (in the Teacher.cpp or similar would prevent that). In the case of a class, you can make the util and base classes friends, which is occasionally helpful (but something to use rarely, as it may be a smell).
I've seen a naming variation, Education::Utils::Teacher, but that's somewhat harder to translate to files (unless you put things into a utils dir) and can also cause name resolution oddness (in some contexts, the compiler may try to use Education::Utils::Teacher instead of Education::Teacher when you didn't mean to). Because of this, I prefer to keep utils as a suffix.
You may want to handle non-member functions in a singleton class for your application. A factory maybe executed from the program, or another object.
C++ supports global functions (non member functions), but, using a single object for the application, "does the trick".
Additionally, since the "Classroom" object may be instantiated with many optional parameters, you may want to assign it, after calling the constructor ( "init" in python ).
// filename: "classrooms.cpp"
class ClassroomClass
{
protected:
int _Room_Size;
int _N_Desks;
int _N_Boards;
int _N_Books;
bool _Has_Globe;
public:
// constructor without parameters,
// but, can be declared with them
ClassroomClass()
{
_Room_Size = 0;
_N_Desks = 0;
_N_Boards = 0;
_N_Books = 0;
_Has_Globe = false;
} // ClassroomClass()
public int get_Room_Size()
{
return _Room_Size;
}
public void set_Room_Size(int Value)
{
_Room_Size = Value;
}
// other "getters" & "setters" functions
// ...
} // class ClassroomClass
class ClassroomFactoryClass
{
public:
void addRequirement(char[] AKey, char[] AValue);
} // class ClassroomFactoryClass
class MyProgramClass
{
public:
ClassroomFactoryClass Factory;
public:
void makeTeacherRoom();
void doSomething();
} // class MyProgramClass
void MyProgramClass::addRequirement(char[] AKey, char[] AValue)
{
...
} // void MyProgramClass::addRequirement(...)
void MyProgramClass::makeTeacherRoom()
{
Factory.addRequirement("n_desks", "10")
Factory.addRequirement("n_boards", "1")
} // void MyProgramClass::makeTeacherRoom(...)
void MyProgramClass::doSomething()
{
...
} // void MyProgramClass::doSomething(...)
int main(char[][] args)
{
MyProgramClass MyProgram = new MyProgramClass();
MyProgram->doSomething();
delete MyProgram();
return 0;
} // main(...)
Cheers
Personally I would make them static members of the class.
class File
{
public:
static bool load( File & file, std::string const & fileName );
private:
std::vector< char > data;
};
int main( void )
{
std::string fileName = "foo.txt";
File myFile;
File::load( myFile, fileName );
}
With static methods they have access to the private data of the class while not belonging to a specific instance of the class. It also means the methods aren't separated from the data they act on, as would be the case if you put them in a utility header somewhere.

Type-casting to an abstract class?

I'm writing an event-based messaging system to be used between the various singleton managers in my game project. Every manager type (InputManager, AudioManager, etc) is derived from a base Manager class and also inherits from an EventHandler class to facilitate message processing, as follows:
class Manager
{ ... }
class EventHandler
{ ...
virtual void onEvent(Event& e) =0;
...
}
class InputManager : public Manager, public EventHandler
{ ...
virtual void InputManager::onEvent(Event& e);
{ ... }
}
Elsewhere I have an EventManager that keeps track of all EventHandlers and is used for broadcasting events to multiple recievers.
class EventManager
{...
addHandlerToGroup(EventHandler& eh);
{ ... }
...
}
Naturally when I'm initializing all of my singleton Managers, I want to be adding them as they're created to the EventManager's list. My problem is that MVC++ complains at compile-time (and as I'm coding with squiggly lines) whenever I attempt to cast my Managers to EventHandlers. I thought it would work as follows:
int main()
{ ...
EventManager* eventM = new EventManager();
...
InputManager* inputM = new InputManager();
eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));
}
The compiler, however, informs me that "a cast to abstract class is not allowed." I was under the impression that you can...after all, polymorphism doesn't do you much good without passing objects back and forth with a bit of flexibility as to how close to the base class they are interpreted. My current workaround looks like this:
int main()
{ ...
EventManager* eventM = new EventManager();
EventHandler* temp;
...
InputManager* inputM = new InputManager();
temp = inputM;
eventM->addHandlerToGroup(*inputM);
}
Which, as far as I can tell, is the same conceptually for what I'm trying to accomplish, if a bit more verbose and less intuitive. Am I completely off as far as how typecasting with polymorphism works? Where am I going wrong?
in EventManager, declare the method addHandlerToGroup as
void addHandlerToGroup(EventHandler* handler);
then, just remove the cast. pass the pointer (in the example inputM) as it is to the addHandler method, and you should be fine :)
InputManager* inputM = new InputManager();
eventM->addHandlerToGroup(dynamic_cast<EventHandler>(inputM));
I think you just lost track of what you were doing. In this code, inputM is an InputManager* and you are trying to cast it to an EventHandler. That is, you are trying to cast a pointer to one class to an instance of another class. That, of course, makes no sense.
You can cast a pointer to an instance of a derived class to a pointer to an instance of one of its base classes. I think that's what you meant to do.

Factory method anti-if implementation

I'm applying the Factory design pattern in my C++ project, and below you can see how I am doing it. I try to improve my code by following the "anti-if" campaign, thus want to remove the if statements that I am having. Any idea how can I do it?
typedef std::map<std::string, Chip*> ChipList;
Chip* ChipFactory::createChip(const std::string& type) {
MCList::iterator existing = Chips.find(type);
if (existing != Chips.end()) {
return (existing->second);
}
if (type == "R500") {
return Chips[type] = new ChipR500();
}
if (type == "PIC32F42") {
return Chips[type] = new ChipPIC32F42();
}
if (type == "34HC22") {
return Chips[type] = new Chip34HC22();
}
return 0;
}
I would imagine creating a map, with string as the key, and the constructor (or something to create the object). After that, I can just get the constructor from the map using the type (type are strings) and create my object without any if. (I know I'm being a bit paranoid, but I want to know if it can be done or not.)
You are right, you should use a map from key to creation-function.
In your case it would be
typedef Chip* tCreationFunc();
std::map<std::string, tCreationFunc*> microcontrollers;
for each new chip-drived class ChipXXX add a static function:
static Chip* CreateInstance()
{
return new ChipXXX();
}
and also register this function into the map.
Your factory function should be somethink like this:
Chip* ChipFactory::createChip(std::string& type)
{
ChipList::iterator existing = microcontrollers.find(type);
if (existing != microcontrollers.end())
return existing->second();
return NULL;
}
Note that copy constructor is not needed, as in your example.
The point of the factory is not to get rid of the ifs, but to put them in a separate place of your real business logic code and not to pollute it. It is just a separation of concerns.
If you're desperate, you could write a jump table/clone() combo that would do this job with no if statements.
class Factory {
struct ChipFunctorBase {
virtual Chip* Create();
};
template<typename T> struct CreateChipFunctor : ChipFunctorBase {
Chip* Create() { return new T; }
};
std::unordered_map<std::string, std::unique_ptr<ChipFunctorBase>> jumptable;
Factory() {
jumptable["R500"] = new CreateChipFunctor<ChipR500>();
jumptable["PIC32F42"] = new CreateChipFunctor<ChipPIC32F42>();
jumptable["34HC22"] = new CreateChipFunctor<Chip34HC22>();
}
Chip* CreateNewChip(const std::string& type) {
if(jumptable[type].get())
return jumptable[type]->Create();
else
return null;
}
};
However, this kind of approach only becomes valuable when you have large numbers of different Chip types. For just a few, it's more useful just to write a couple of ifs.
Quick note: I've used std::unordered_map and std::unique_ptr, which may not be part of your STL, depending on how new your compiler is. Replace with std::map/boost::unordered_map, and std::/boost::shared_ptr.
No you cannot get rid of the ifs. the createChip method creats a new instance depending on constant (type name )you pass as argument.
but you may optimaze yuor code a little removing those 2 line out of if statment.
microcontrollers[type] = newController;
return microcontrollers[type];
To answer your question: Yes, you should make a factory with a map to functions that construct the objects you want. The objects constructed should supply and register that function with the factory themselves.
There is some reading on the subject in several other SO questions as well, so I'll let you read that instead of explaining it all here.
Generic factory in C++
Is there a way to instantiate objects from a string holding their class name?
You can have ifs in a factory - just don't have them littered throughout your code.
struct Chip{
};
struct ChipR500 : Chip{};
struct PIC32F42 : Chip{};
struct ChipCreator{
virtual Chip *make() = 0;
};
struct ChipR500Creator : ChipCreator{
Chip *make(){return new ChipR500();}
};
struct PIC32F42Creator : ChipCreator{
Chip *make(){return new PIC32F42();}
};
int main(){
ChipR500Creator m; // client code knows only the factory method interface, not the actuall concrete products
Chip *p = m.make();
}
What you are asking for, essentially, is called Virtual Construction, ie the ability the build an object whose type is only known at runtime.
Of course C++ doesn't allow constructors to be virtual, so this requires a bit of trickery. The common OO-approach is to use the Prototype pattern:
class Chip
{
public:
virtual Chip* clone() const = 0;
};
class ChipA: public Chip
{
public:
virtual ChipA* clone() const { return new ChipA(*this); }
};
And then instantiate a map of these prototypes and use it to build your objects (std::map<std::string,Chip*>). Typically, the map is instantiated as a singleton.
The other approach, as has been illustrated so far, is similar and consists in registering directly methods rather than an object. It might or might not be your personal preference, but it's generally slightly faster (not much, you just avoid a virtual dispatch) and the memory is easier to handle (you don't have to do delete on pointers to functions).
What you should pay attention however is the memory management aspect. You don't want to go leaking so make sure to use RAII idioms.

Dynamic binding in C++

I'm implementing a CORBA like server. Each class has remotely callable methods and a dispatch method with two possible input, a string identifying the method or an integer which would be the index of the method in a table. A mapping of the string to the corresponding integer would be implemented by a map.
The caller would send the string on the first call and get back the integer with the response so that it simply has to send the integer on subsequent calls. It is just a small optimization. The integer may be assigned dynamically on demand by the server object.
The server class may be derived from another class with overridden virtual methods.
What could be a simple and general way to define the method binding and the dispatch method ?
Edit: The methods have all the same signature (no overloading). The methods have no parameters and return a boolean. They may be static, virtual or not, overriding a base class method or not. The binding must correctly handle method overriding.
The string is class hierarchy bound. If we have A::foo() identified by the string "A.foo", and a class B inherits A and override the method A::foo(), it will still be identified as "A.foo", but the dispatcher will call A::foo if the server is an A object and B::foo if it is a B object.
Edit (6 apr): In other words, I need to implement my own virtual method table (vftable) with a dynamic dispatch method using a string key to identify the method to call. The vftable should be shared among objects of the same class and behave as expected for polymorphism (inherited method override).
Edit (28 apr): See my own answer below and the edit at the end.
Have you considered using a combination of boost::bind and boost::function? Between these two utilities you can easily wrap any C++ callable in a function object, easily store them in containers, and generally expect it all to "just work". As an example, the following code sample works exactly the way you would expect.
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
using namespace std;
struct A { virtual void hello() { cout << "Hello from A!" << endl; } };
struct B : public A { virtual void hello() { cout << "Hello from B!" << endl; } };
int main( int argc, char * argv[] )
{
A a;
B b;
boost::function< void () > f1 = boost::bind( &A::hello, a );
boost::function< void () > f2 = boost::bind( &A::hello, b );
f1(); // prints: "Hello from A!"
f2(); // prints: "Hello from B!"
return 0;
}
It looks like you're looking for something like reflection or delegates -- I'm not 100% sure what you're trying to accomplish, but it seems the best way of doing that is just having a map of function pointers:
typedef size_t (*CommonMethodPointerType)(const unsigned char *);
std::map<std::string, CommonMethodPointerType> functionMapping;
size_t myFunc(const std::string& functionName, const unsigned char * argument) {
std::map<std::string, CommonMethodPointerType>::iterator functionPtrIterator
= functionMapping.find(functionName);
if (FunctionPtrIterator == functionMapping.end())
return ERROR_CODE;
return (*functionPtrIterator)(argument);
}
You could implement some form of optimization similar to your integer by returning the iterator to the client so long as you know the mapping will not change.
If you're looking for "dynamic binding" like that allowed in C# or dynamic languages like PHP, unfortunately you really can't do that -- C++ destroys type information when code is compiled.
Hope that helps!
You might like to rephrase the question slightly as static and dynamic binding actually have a specific meaning in C++.
For example, default values for parameters are determined at compile time so if I have a virtual method in a base class that declares default values for its parameters then those values are set at compile time.
Any new default values for these parameters that are declared in a derived class will be ignored at run time with the result being that the default parameter values in the base class will be used, even though you called the member function in the derived class.
The default parameter values are said to be statically bound.
Scott Meyers discusses this in an item in his excellent book "Effective C++".
HTH
Qt4 has a nice dynamic binding system that's made possible via their "Meta-Object Compiler" (moc). There's a nice writeup on it on their Qt Object Model page.
Here is a way do dynamically load classes from shared libraries on Linux http://www.linuxjournal.com/article/3687?page=0,0
There is also a stackoverflow question on this
C++ Dynamic Shared Library on Linux
The same can be done in Windows by dynamically loading C functions from DLLs and then loading those.
The map part is trivial after you have your dynamic loading solution
The really good book Advanced C++ programming idioms and idioms by James O. Coplien has a section on Incremental loading
Here is an example of my actual method. It Just Works (c) but I'm pretty sure a much cleaner and better way exist. It compiles and runs with g++ 4.4.2 as is. Removing the instruction in the constructor would be great, but I couldn't find a way to achieve this. The Dispatcher class is basically a dispatchable method table and each instance must have a pointer on its table.
Note: This code will implicitly make all dispatched methods virtual.
#include <iostream>
#include <map>
#include <stdexcept>
#include <cassert>
// Forward declaration
class Dispatchable;
//! Abstract base class for method dispatcher class
class DispatcherAbs
{
public:
//! Dispatch method with given name on object
virtual void dispatch( Dispatchable *obj, const char *methodName ) = 0;
virtual ~DispatcherAbs() {}
};
//! Base class of a class with dispatchable methods
class Dispatchable
{
public:
virtual ~Dispatchable() {}
//! Dispatch the call
void dispatch( const char *methodName )
{
// Requires a dispatcher singleton assigned in derived class constructor
assert( m_dispatcher != NULL );
m_dispatcher->dispatch( this, methodName );
}
protected:
DispatcherAbs *m_dispatcher; //!< Pointer on method dispatcher singleton
};
//! Class type specific method dispatcher
template <class T>
class Dispatcher : public DispatcherAbs
{
public:
//! Define a the dispatchable method type
typedef void (T::*Method)();
//! Get dispatcher singleton for class of type T
static Dispatcher *singleton()
{
static Dispatcher<T> vmtbl;
return &vmtbl;
}
//! Add a method binding
void add( const char* methodName, Method method )
{ m_map[methodName] = method; }
//! Dispatch method with given name on object
void dispatch( Dispatchable *obj, const char *methodName )
{
T* tObj = dynamic_cast<T*>(obj);
if( tObj == NULL )
throw std::runtime_error( "Dispatcher: class mismatch" );
typename MethodMap::const_iterator it = m_map.find( methodName );
if( it == m_map.end() )
throw std::runtime_error( "Dispatcher: unmatched method name" );
// call the bound method
(tObj->*it->second)();
}
protected:
//! Protected constructor for the singleton only
Dispatcher() { T::initDispatcher( this ); }
//! Define map of dispatchable method
typedef std::map<const char *, Method> MethodMap;
MethodMap m_map; //! Dispatch method map
};
//! Example class with dispatchable methods
class A : public Dispatchable
{
public:
//! Construct my class and set dispatcher
A() { m_dispatcher = Dispatcher<A>::singleton(); }
void method1() { std::cout << "A::method1()" << std::endl; }
virtual void method2() { std::cout << "A::method2()" << std::endl; }
virtual void method3() { std::cout << "A::method3()" << std::endl; }
//! Dispatcher initializer called by singleton initializer
template <class T>
static void initDispatcher( Dispatcher<T> *dispatcher )
{
dispatcher->add( "method1", &T::method1 );
dispatcher->add( "method2", &T::method2 );
dispatcher->add( "method3", &T::method3 );
}
};
//! Example class with dispatchable methods
class B : public A
{
public:
//! Construct my class and set dispatcher
B() { m_dispatcher = Dispatcher<B>::singleton(); }
void method1() { std::cout << "B::method1()" << std::endl; }
virtual void method2() { std::cout << "B::method2()" << std::endl; }
//! Dispatcher initializer called by singleton initializer
template <class T>
static void initDispatcher( Dispatcher<T> *dispatcher )
{
// call parent dispatcher initializer
A::initDispatcher( dispatcher );
dispatcher->add( "method1", &T::method1 );
dispatcher->add( "method2", &T::method2 );
}
};
int main( int , char *[] )
{
A *test1 = new A;
A *test2 = new B;
B *test3 = new B;
test1->dispatch( "method1" );
test1->dispatch( "method2" );
test1->dispatch( "method3" );
std::cout << std::endl;
test2->dispatch( "method1" );
test2->dispatch( "method2" );
test2->dispatch( "method3" );
std::cout << std::endl;
test3->dispatch( "method1" );
test3->dispatch( "method2" );
test3->dispatch( "method3" );
return 0;
}
Here is the program output
A::method1()
A::method2()
A::method3()
B::method1()
B::method2()
A::method3()
B::method1()
B::method2()
A::method3()
Edit (28 apr): The answers to this related question was enlightening. Using a virtual method with an internal static variable is preferable to using a member pointer variable that needs to be initialized in the constructor.
I've seen both your example and the answer to the other question. But if you talk about the m_dispatcher member, the situation is very different.
For the original question, there's no way to iterate over methods of a class. You might only remove the repetition in add("method", T::method) by using a macro:
#define ADD(methodname) add(#methodname, T::methodname)
where the '#' will turn methodname into a string like required (expand the macro as needed). In case of similarly named methods, this removes a source of potential typos, hence it is IMHO very desirable.
The only way to list method names IMHO is by parsing output of "nm" (on Linux, or even on Windows through binutils ports) on such files (you can ask it to demangle C++ symbols). If you want to support this, you may want initDispatcher to be defined in a separate source file to be auto-generated. There's no better way than this, and yes, it may be ugly or perfect depending on your constraints. Btw, it also allows to check that authors are not overloading methods. I don't know if it would be possible to filter public methods, however.
I'm answering about the line in the constructor of A and B. I think the problem can be solved with the curiously recurring template pattern, applied on Dispatchable:
template <typename T>
class Dispatchable
{
public:
virtual ~Dispatchable() {}
//! Dispatch the call
void dispatch( const char *methodName )
{
dispatcher()->dispatch( this, methodName );
}
protected:
static Dispatcher<T> dispatcher() {
return Dispatcher<T>::singleton();
//Or otherwise, for extra optimization, using a suggestion from:
//http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
static Dispatcher<T>& disp = Dispatcher<T>::singleton();
return disp;
}
};
Disclaimer: I couldn't test-compile this (I'm away from a compiler). You may need to forward-declare Dispatcher, but since it gets a template argument I guess argument-dependant lookup makes that unnecessary (I'm not enough of a C++ guru to be sure of this).
I've added a dispatcher() method for convenience, if it is needed elsewhere (otherwise you can inline it in dispatch()).
The reason CRTP is so simple here and so complicated in the other thread is that here your member was not static. I first thought of making it static, then I thought there was no reason for saving the result of the call to singleton() and waste memory, then I looked it up and found this solution. I'm dubious if the extra reference in dispatcher() does save any extra time.
In any case, if a m_dispatcher member was needed, it could be initialized in the Dispatchable() constructor.
About your example, since initDispatcher() is a template method, I frankly doubt it is necessary to readd method1 and method2. A::initDispatcher(Dispatcher<B> dispatcher) will correctly add B::method1 to dispatcher.
By the way - don't forget that the numeric position of virtual functions dispatched from a vtable correspond identically, with all compilers, to the sequence they appear in the corresponding header file. You may be able to take advantage of that. That is a core principle upon which Microsoft COM technology is based.
Also, you might consider an approach published in "Game Programming Gems" (first volume) by Mark DeLoura. The article is entitled a "generic function binding interface" and is intended for RPC / network binding of functions. It may be exactly what you want.
class Report //This denotes the base class of C++ virtual function
{
public:
virtual void create() //This denotes the C++ virtual function
{
cout <<"Member function of Base Class Report Accessed"<<endl;
}
};
class StudentReport: public Report
{
public:
void create()
{
cout<<"Virtual Member function of Derived class StudentReportAccessed"<<endl;
}
};
void main()
{
Report *a, *b;
a = new Report();
a->create();
b = new StudentReport();
b->create();
}

How can I keep track of (enumerate) all classes that implement an interface

I have a situation where I have an interface that defines how a certain class behaves in order to fill a certain role in my program, but at this point in time I'm not 100% sure how many classes I will write to fill that role. However, at the same time, I know that I want the user to be able to select, from a GUI combo/list box, which concrete class implementing the interface that they want to use to fill a certain role. I want the GUI to be able to enumerate all available classes, but I would prefer not to have to go back and change old code whenever I decide to implement a new class to fill that role (which may be months from now)
Some things I've considered:
using an enumeration
Pros:
I know how to do it
Cons
I will have to update update the enumeration when I add a new class
ugly to iterate through
using some kind of static list object in the interface, and adding a new element from within the definition file of the implementing class
Pros:
Wont have to change old code
Cons:
Not even sure if this is possible
Not sure what kind of information to store so that a factory method can choose the proper constructor ( maybe a map between a string and a function pointer that returns a pointer to an object of the interface )
I'm guessing this is a problem (or similar to a problem) that more experienced programmers have probably come across before (and often), and there is probably a common solution to this kind of problem, which is almost certainly better than anything I'm capable of coming up with. So, how do I do it?
(P.S. I searched, but all I found was this, and it's not the same: How do I enumerate all items that implement a generic interface?. It appears he already knows how to solve the problem I'm trying to figure out.)
Edit: I renamed the title to "How can I keep track of... " rather than just "How can I enumerate..." because the original question sounded like I was more interested in examining the runtime environment, where as what I'm really interested in is compile-time book-keeping.
Create a singleton where you can register your classes with a pointer to a creator function.
In the cpp files of the concrete classes you register each class.
Something like this:
class Interface;
typedef boost::function<Interface* ()> Creator;
class InterfaceRegistration
{
typedef map<string, Creator> CreatorMap;
public:
InterfaceRegistration& instance() {
static InterfaceRegistration interfaceRegistration;
return interfaceRegistration;
}
bool registerInterface( const string& name, Creator creator )
{
return (m_interfaces[name] = creator);
}
list<string> names() const
{
list<string> nameList;
transform(
m_interfaces.begin(), m_interfaces.end(),
back_inserter(nameList)
select1st<CreatorMap>::value_type>() );
}
Interface* create(cosnt string& name ) const
{
const CreatorMap::const_iterator it
= m_interfaces.find(name);
if( it!=m_interfaces.end() && (*it) )
{
return (*it)();
}
// throw exception ...
return 0;
}
private:
CreatorMap m_interfaces;
};
// in your concrete classes cpp files
namespace {
bool registerClassX = InterfaceRegistration::instance("ClassX", boost::lambda::new_ptr<ClassX>() );
}
ClassX::ClassX() : Interface()
{
//....
}
// in your concrete class Y cpp files
namespace {
bool registerClassY = InterfaceRegistration::instance("ClassY", boost::lambda::new_ptr<ClassY>() );
}
ClassY::ClassY() : Interface()
{
//....
}
I vaguely remember doing something similar to this many years ago. Your option (2) is pretty much what I did. In that case it was a std::map of std::string to std::typeinfo. In each, .cpp file I registered the class like this:
static dummy = registerClass (typeid (MyNewClass));
registerClass takes a type_info object and simply returns true. You have to initialize a variable to ensure that registerClass is called during startup time. Simply calling registerClass in the global namespace is an error. And making dummy static allow you to reuse the name across compilation units without a name collision.
I referred to this article to implement a self-registering class factory similar to the one described in TimW's answer, but it has the nice trick of using a templated factory proxy class to handle the object registration. Well worth a look :)
Self-Registering Objects in C++ -> http://www.ddj.com/184410633
Edit
Here's the test app I did (tidied up a little ;):
object_factory.h
#include <string>
#include <vector>
// Forward declare the base object class
class Object;
// Interface that the factory uses to communicate with the object proxies
class IObjectProxy {
public:
virtual Object* CreateObject() = 0;
virtual std::string GetObjectInfo() = 0;
};
// Object factory, retrieves object info from the global proxy objects
class ObjectFactory {
public:
static ObjectFactory& Instance() {
static ObjectFactory instance;
return instance;
}
// proxies add themselves to the factory here
void AddObject(IObjectProxy* object) {
objects_.push_back(object);
}
size_t NumberOfObjects() {
return objects_.size();
}
Object* CreateObject(size_t index) {
return objects_[index]->CreateObject();
}
std::string GetObjectInfo(size_t index) {
return objects_[index]->GetObjectInfo();
}
private:
std::vector<IObjectProxy*> objects_;
};
// This is the factory proxy template class
template<typename T>
class ObjectProxy : public IObjectProxy {
public:
ObjectProxy() {
ObjectFactory::Instance().AddObject(this);
}
Object* CreateObject() {
return new T;
}
virtual std::string GetObjectInfo() {
return T::TalkToMe();
};
};
objects.h
#include <iostream>
#include "object_factory.h"
// Base object class
class Object {
public:
virtual ~Object() {}
};
class ClassA : public Object {
public:
ClassA() { std::cout << "ClassA Constructor" << std::endl; }
~ClassA() { std::cout << "ClassA Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassA"; }
};
class ClassB : public Object {
public:
ClassB() { std::cout << "ClassB Constructor" << std::endl; }
~ClassB() { std::cout << "ClassB Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassB"; }
};
objects.cpp
#include "objects.h"
// Objects get registered here
ObjectProxy<ClassA> gClassAProxy;
ObjectProxy<ClassB> gClassBProxy;
main.cpp
#include "objects.h"
int main (int argc, char * const argv[]) {
ObjectFactory& factory = ObjectFactory::Instance();
for (int i = 0; i < factory.NumberOfObjects(); ++i) {
std::cout << factory.GetObjectInfo(i) << std::endl;
Object* object = factory.CreateObject(i);
delete object;
}
return 0;
}
output:
This is ClassA
ClassA Constructor
ClassA Destructor
This is ClassB
ClassB Constructor
ClassB Destructor
If you're on Windows, and using C++/CLI, this becomes fairly easy. The .NET framework provides this capability via reflection, and it works very cleanly in managed code.
In native C++, this gets a little bit trickier, as there's no simple way to query the library or application for runtime information. There are many frameworks that provide this (just look for IoC, DI, or plugin frameworks), but the simplest means of doing it yourself is to have some form of configuration which a factory method can use to register themselves, and return an implementation of your specific base class. You'd just need to implement loading a DLL, and registering the factory method - once you have that, it's fairly easy.
Something you can consider is an object counter. This way you don't need to change every place you allocate but just implementation definition. It's an alternative to the factory solution. Consider pros/cons.
An elegant way to do that is to use the CRTP : Curiously recurring template pattern.
The main example is such a counter :)
This way you just have to add in your concrete class implementation :
class X; // your interface
class MyConcreteX : public counter<X>
{
// whatever
};
Of course, it is not applicable if you use external implementations you do not master.
EDIT:
To handle the exact problem you need to have a counter that count only the first instance.
my 2 cents
There is no way to query the subclasses of a class in (native) C++.
How do you create the instances? Consider using a Factory Method allowing you to iterate over all subclasses you are working with. When you create an instance like this, it won't be possible to forget adding a new subclass later.