Working on a solid Command Pattern with shared_ptr - c++

I am trying to implement a very clean Command Pattern in a library.
I have the following structure right now (a few parts are still being finished up):
users (client-code) have some Object, call it "Manager"
Manager holds a collection of shared_ptr<Foo>
Manager provides access to the collection by returning shared_ptr<Foo>
I have a Command abstract class and a hierarchy of commands for actions to perform on Foo
Client code should not call Command::execute(), only Manager should, Manager::execute(shared_ptr<Command>), so that it can handle undo/redo
I would like to follow the following rules:
users (client-code) have some Object, call it "Manager"
Manager holds a collection of shared_ptr<Foo>
Manager provides access to the collection by returning shared_ptr<const Foo>
I have a Command abstract class and a hierarchy of commands for actions to perform on Foo
Client code cannot (without workarounds) call Command::execute(), only Manager can, Manager::execute(shared_ptr<Command>), so that it can handle undo/redo and get non-const smart pointers
A Manager must be able to allow Command objects to access and modify shared_ptr<Foo> even though the user initializes Command objecst with shared_ptr<const Foo>
I am just trying to figure out the best way to handle giving out shared_ptr<const Foo> while allowing number 5 and 6 to work.
Is there any example/design pattern that does this which I could learn from? Is this a good idea compared to what I already have/am working on?

I think this passkey pattern should be the right thing for you:
class CommandExecuteKey{
private:
friend class Manager;
CommandExecuteKey(){}
};
class Command{
public:
// usual stuff
void execute(CommandExecuteKey);
};
class Manager{
public
void execute(Command& cmd){
// do whatever you need to do
cmd.execute(CommandExecuteKey());
}
};
Now, Command doesn't know anything about Manager, only about the key that is needed for the execute function. The user won't be able to call the execute method directly, as only Manager can create CommandExecuteKey objects, thanks to a private constructor and friendship.
int main(){
Command cmd;
Manager mgr;
//cmd.execute(CommandExecuteKey()); // error: constructor not accessible
mgr.execute(cmd); // works fine, Manager can create a key
}
Now, for your 6th point:
When you get the command in, search all your shared_ptr<Foo>s for the correct object (using the saved shared_ptr of the command as a search-key) and then pass that mutable one from your internal shared_ptrs back to the command.

Since it wouldn't make any sense to me otherwise, I'm going to assume that
your library provides the Manager class (or at least a base class), and
clients have to use that class to invoke a Command.
In that case, maybe something like this could work:
void Manager::execute(Command& cmd, shared_ptr<Foo const> const& target)
{
shared_ptr<Foo> mutableTarget = this->LookupMutableFoo(mutableTarget); // throws if not found
cmd.execute(mutableTarget); // client cannot invoke without mutable pointer
}
// or, if the "target" needs to be stored in the Command you could use something like this:
void Manager::execute(Command& cmd)
{
shared_ptr<Foo> mutableTarget = this->LookupMutableFoo(cmd.GetTarget()); // throws if not found
cmd.execute(mutableTarget); // client cannot invoke without mutable pointer
}
I'm not sure though if using const is the best solution here. Maybe you should wrap your Foo objects in e.g. ClientFoo objects. The manager only hands out pointers to ClientFoo. The manager can then (e.g. via friend) get the Foo from the ClientFoo, and use it to invoke the Command.

I'm not following your question 100%, but here goes...
The only thing I can think of for #5 is to make Command::execute private/protected and make Manager a friend of Command. The downside of this approach is that you've now introduced a dependency from Command to Manager.
As for #6, if the user's shared_ptr<const Foo> objects were originated from Manager's shared_ptr<Foo> collection, then Manager should be able to safely const_pointer_cast shared_ptr<const Foo*> back into shared_ptr<Foo*>. If Manager attempts to const cast a shared_ptr<const Foo*>, where the pointee is an actual constant object, you'll get undefined behavior.
I've thought of another solution for #5:
Define an ExecutableCommand class, derived from Command. ExecutableCommand has an added method to invoke the command, to be used only by Manager. Clients can only access ExecutableCommand objects via pointers/references to Command. When a Manager wants to invoke a Command, it downcasts it to a ExecutableCommand to gain access to the invocation interface.
Working example (including const_pointer_cast for #6):
#include <iostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost;
//------------------------------------------------------------------------------
struct Foo
{
Foo(int x) : x(x) {}
void print() {++x; cout << "x = " << x << "\n";} // non-const
int x;
};
//------------------------------------------------------------------------------
struct Command
{
// Interface accessible to users
std::string name;
private:
virtual void execute() = 0;
};
//------------------------------------------------------------------------------
struct ExecutableCommand : public Command
{
// Only accessible to Manager
virtual void execute() {} // You may want to make this pure virtual
};
//------------------------------------------------------------------------------
struct PrintCommand : public ExecutableCommand
{
PrintCommand(shared_ptr<const Foo> foo)
: foo_( const_pointer_cast<Foo>(foo) ) {}
void execute() {foo_->print();}
private:
shared_ptr<Foo> foo_;
};
//------------------------------------------------------------------------------
struct Manager
{
void execute(Command& command)
{
ExecutableCommand& ecmd = dynamic_cast<ExecutableCommand&>(command);
ecmd.execute();
}
void addFoo(shared_ptr<Foo> foo) {fooVec.push_back(foo);}
shared_ptr<const Foo> getFoo(size_t index) {return fooVec.at(index);}
private:
std::vector< shared_ptr<Foo> > fooVec;
};
//------------------------------------------------------------------------------
int main()
{
Manager mgr;
mgr.addFoo( shared_ptr<Foo>(new Foo(41)) );
Command* print = new PrintCommand(mgr.getFoo(0));
// print.execute() // Not allowed
mgr.execute(*print);
delete print;
}

Related

c++ - access pointer to call method (using callbacks etc)

I am trying to figure out how to do this.
I have 2 classes -
class Caller(){
//constructs Callee
void onEventFired(){
//need to call a function on an obj
//which I dont have access to here
//objptr->funcA
}
};
class Callee(){
//it has access to an instance of caller object
private:
void setup(){
std::unique_ptr objptr = make_unique<SampleClass>....
//create unique ptr of obj
//can pass the objptr to Caller through a
//separate function but probably not clean ??
}
};
Chain of events -
Caller creates the callee instance during its own construction, – later, callee's setup function is called which creates SampleClass pointer. at some point later, the periodic event starts to fire up thats when I want call SampleClass's funcA from within Caller
One way is to pass the raw SampleClass pointer to the Caller class through a separate function but ideally I don't want the class Caller to have access to that.
Is there a way using some callbacks which I can do this cleanly.
Your question is a little weak in motivation, so let's beef it up just a tad.
Suppose that Caller accepts registrations for things that want to be called back whenever EVENT_FIRED happens. So, the system has something like this:
//... initialize all callees
//... wait for event
switch (event) {
//...
case EVENT_FIRED:
//...
//callback all interested callees
Caller::instance().onEventFired();
break;
//...
default:
//...
break;
};
Typically, you will want the callees to register themselves with the Caller instance, so that they get notification of the event via their registered callback.
In order to accept registrations, you would use some kind of container in the caller to track them.
class Caller {
public:
struct Callback {
virtual ~Callback () = default;
virtual void fire () = 0;
};
static Caller & instance () {
static Caller one;
return one;
}
template <typename CALLBACK, int EVENT>
void subscribe () {
std::unique_ptr<Callback> cb(std::make_unique<CALLBACK>());
callbacks_[EVENT].push_back(std::move(cb));
}
//...
void onEventFired () {
for (auto &cb : callbacks_[EVENT_FIRED]) cb->fire();
}
private:
typedef std::list<std::unique_ptr<Callback>> CallbackList;
std::unordered_map<int, CallbackList> callbacks_;
Caller () = default;
Caller (const Caller &) = delete;
Caller & operator = (Caller) = delete;
~Caller () = default;
};
The Caller now implements the Callback interface, and makes its registration during setup.
class Callee : public Caller::Callback {
public:
static void setup () {
Caller::instance().subscribe<Callee, EVENT_FIRED>();
}
void fire () { std::cout << "You're fired!\n"; }
};
Try it online!
Here are 2 references may be what you're looking for.
The Attorney-Client idiom, and pass-key pattern.
The Attorney-Client idiom is a method that add a proxy class.
The proxy class is a friend of the class which needs access.
[Callee] - [Proxy] - [Caller] relationship is built.
Pass-Key pattern is a relatively simple method to solve the problem.
The main idea is same that uses friend keyword.
However, it's using class template, rooted in template meta programming.
For more sophisticated usage, take a look at this version. (the last answer)

Creating Command objects at run-time

I'm trying to write a console for a game engine which will allow me to type in commands to perform tasks, such as change the map, spawn an enemy etc.
I've been trying to do this with the Command pattern (following the example from gameprogrammingpatterns.com). See below for the outline of my current code structure.
parseCommand processes the string from the user, extracting the command name and arguments (currently using just whitespace separation). The next step is where I'm stuck. I need to create a Command* somehow to call execute on but I only have the string name of the command.
I could have a giant bunch of if statements in my parseCommand function, such as:
if (cmdName == "spawn")
return new SpawnEnemyCommand();
Alternatively I could store a pointer to each command in myConsole class, e.g. Command *spawnNewEnemy = new SpawnNewEnemy(); and then in parseCommand do if (cmdName == "spawn") spawnNewEnemy->execute();. This second option seems to be how the gameprogrammingpatterns book does it.
Neither of these options seems very practical if I end up with hundreds of console commands. I've studied all the articles and posts I can find on this pattern but it isn't helping clarify the situation for me.
How can I cleanly instantiate the correct Command object from within parseCommand?
Command interface base class:
class Command {
public:
virtual ~Command() { }
virtual void execute() = 0;
};
Example interface implementation:
class SpawnEnemyCommand : public Command {
public:
void execute() {
// method calls to perform command go here
}
};
Console class header:
class Console {
public:
Command* parseCommand(std::string);
bool validateCommand(std::string, std::vector<std::string>);
};
By relying on a dictionary (e.g, std::unordered_map or std::map) that maps a command identifier (i.e., a std::string object) to a Command object, you can design a factory with dynamic registry for your Command objects.
First, extend Command by including another virtual member function, clone(), that allows us to implement The Prototype Pattern:
class Command {
public:
// ...
virtual std::unique_ptr<Command> clone() const = 0;
};
The clone() virtual member function does what its name suggests: it clones the object. That is, SpawnEnemyCommand would override Command::clone() in the following way:
class SpawnEnemyCommand : public Command {
public:
// ...
std::unique_ptr<Command> clone() const override {
// simply create a copy of itself
return std::make_unique<SpawnEnemyCommand>(*this);
}
};
This way, your command objects can be copied polymorphically through the Command interface – i.e., you don't need to know the concrete type of the command to be copied. All you need to do to copy a Command object is to call its clone() virtual member function. For example, the following function copies the Command passed as an argument regardless of the underlying concrete type:
std::unique_ptr<Command> CopyCommand(const Command& cmd) {
return cmd.clone();
}
With this in mind, you are ready to design a factory for command objects, CommandFactory, that supports dynamically registering your command objects:
class CommandFactory {
public:
void registerCommand(std::string id, std::unique_ptr<Command>);
std::unique_ptr<Command> createCommand(std::string id) const;
private:
std::unordered_map<std::string, std::unique_ptr<Command>> registry_;
};
It all boils down to a std::unordered_map<std::string, std::unique_ptr<Command>> data member. Indexing this data member by a command identifier, which is an std::string, we retrieve a Command object – This is the prototype object we will use for cloning.
The registerCommand() member function adds a Command prototype to the registry:
void CommandFactory::registerCommand(std::string cmdId, std::unique_ptr<Command> cmd) {
registry_[cmdId] = std::move(cmd);
}
The createCommand() member function clones the Command prototype corresponding to the requested command identifier:
std::unique_ptr<Command> CommandFactory::createCommand(std::string cmdId) const {
auto const it = registry_.find(cmdId);
if (it == registry_.end())
return nullptr; // no such a command in the registry
auto const& cmdPtr = it->second;
return cmdPtr->clone();
}
As an example program:
auto main() -> int {
CommandFactory factory;
factory.registerCommand("spawn", std::make_unique<SpawnEnemyCommand>());
// ...
auto cmdPtr = factory.createCommand("spawn");
cmdPtr->execute();
}
You can also extend this factory to add support for dynamically deregistering your already-registered Command prototypes.

How to pass a Function pointer without exposing class details

I'm creating a library that needs to allow the user to set a callback function.
The interface of this library is as below:
// Viewer Class Interface Exposed to user
/////////////////////////////
#include "dataType_1.h"
#include "dataType_2.h"
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2* ) );
private:
dataType_1* (*CallbackFunction) (dataType_2* );
}
In a typical usage, the user needs to access an object of dataType_3 within the callback.
However, this object is only known only to his program, like below.
// User usage
#include "Viewer.h"
#include "dataType_3.h"
// Global Declaration needed
dataType_3* objectDataType3;
dataType_1* aFunction( dataType_2* a)
{
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
myViewer->SetCallbackFunction( &aFunction );
}
My Question is as follows:
How do I avoid using an ugly global variable for objectDataType3 ?
(objectDataType3 is part of libraryFoo and all the other objects dataType_1, dataType_2 & Viewer are part of libraryFooBar) Hence I would like them to remain as separate as possible.
Don't use C in C++.
Use an interface to represent the fact you want a notification.
If you want objects of type dataType_3 to be notified of an event that happens in the viewer then just make this type implement the interface then you can register the object directly with the viewer for notification.
// The interface
// Very close to your function pointer definition.
class Listener
{
public: virtual dataType_1* notify(dataType_2* param) = 0;
};
// Updated viewer to use the interface defineition rather than a pointer.
// Note: In the old days of C when you registered a callback you normally
// also registered some data that was passed to the callback
// (see pthread_create for example)
class Viewer
{
// Set (or Add) a listener.
void SetNotifier(Listener* l) { listener = l; }
// Now you can just inform all objects that are listening
// directly via the interface. (remember to check for NULL listener)
void NotifyList(dataType_2* data) { if (listener) { listener->notify(data); }
private:
Listener* listener;
};
int main()
{
dataType_3 objectDataType3; // must implement the Listener interface
Viewer viewer;
viewer.SetNotifier(&objectDataType3);
}
Use Boost.Function:
class Viewer
{
void SetCallbackFuntion(boost::function<datatype_1* (dataType_2*)> func);
private:
boost::function<datatype_1* (dataType_2*)> CallbackFunction;
}
Then use Boost.Bind to pass the member function pointer together with your object as the function.
If you don't want or can't use boost, the typical pattern around callback functions like this is that you can pass a "user data" value (mostly declared as void*) when registering the callback. This value is then passed to the callback function.
The usage then looks like this:
dataType_1* aFunction( dataType_2* a, void* user_ptr )
{
// Cast user_ptr to datatype_3
// We know it works because we passed it during set callback
datatype_3* objectDataType3 = reinterpret_cast<datatype_3*>(user_ptr);
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
dataType_3 objectDataType3; // No longer needs to be global
myViewer->SetCallbackFunction( &aFunction, &objectDataType3 );
}
The implementation on the other side only requires to save the void* along with the function pointer:
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2*, void*), void* user_ptr );
private:
dataType_1* (*CallbackFunction) (dataType_2*, void*);
void* user_ptr;
}
boost::/std:: function is the solution here. You can bind member functions to them, and in addition functors and lambdas, if you have a lambda compiler.
struct local {
datatype3* object;
local(datatype3* ptr)
: object(ptr) {}
void operator()() {
object->func();
}
};
boost::function<void()> func;
func = local(object);
func(); // calls object->func() by magic.
Something like this is simple to do:
class Callback
{
public:
virtual operator()()=0;
};
template<class T>
class ClassCallback
{
T* _classPtr;
typedef void(T::*fncb)();
fncb _cbProc;
public:
ClassCallback(T* classPtr,fncb cbProc):_classPtr(classPtr),_cbProc(cbProc){}
virtual operator()(){
_classPtr->*_cbProc();
}
};
Your Viewer class would take a callback, and call it using the easy syntax:
class Viewer
{
void SetCallbackFuntion( Callback* );
void OnCallCallback(){
m_cb->operator()();
}
}
Some other class would register the callback with the viewer by using the ClassCallback template specialization:
// User usage
#include "Viewer.h"
#include "dataType_3.h"
main()
{
Viewer* myViewer;
dataType_3 objectDataType3;
myViewer->SetCallbackFunction( new ClassCallback<dataType_3>(&objectDataType3,&dataType_3::DoSomething));
}
You're asking several questions mixed up in here and this is going to cause you lots of confusion in your answers.
I'm going to focus on your issue with dataType_3.
You state:
I would like to avoid declaring or
including dataType_3 in my library as
it has huge dependencies.
What you need to do is make an interface class for dataType_3 that gives the operations -- the footprint -- of dataType_3 without defining everything in it. You'll find tips on how to do that in this article (among other places). This will allow you to comfortably include a header that gives the footprint for dataType_3 without bringing in all of its dependencies. (If you've got dependencies in the public API you may have to reuse that trick for all of those as well. This can get tedious, but this is the price of having a poorly-designed API.)
Once you've got that, instead of passing in a function for callback consider having your "callback" instead be a class implementing a known interface. There are several advantages to doing this which you can find in the literature, but for your specific example there's a further advantage. You can inherit that interface complete with an instantiated dataType_3 object in the base class. This means that you only have to #include the dataType_3 interface specification and then use the dataType_3 instance provided for you by the "callback" framework.
If you have the option of forcing some form of constraints on Viewer, I would simply template that, i.e.
template <typename CallBackType>
class Viewer
{
public:
void SetCallbackFunctor(CallBackType& callback) { _callee = callback; }
void OnCallback()
{
if (_callee) (*_callee)(...);
}
private:
// I like references, but you can use pointers
boost::optional<CallBackType&> _callee;
};
Then in your dataType_3 implement the operator() to do as needed, to use.
int main(void)
{
dataType_3 objectDataType3;
// IMHO, I would construct with the objectDataType3, rather than separate method
// if you did that, you can hold a direct reference rather than pointer or boost::optional!
Viewer<dataType_3> viewer;
viewer.SetCallbackFunctor(objectDataType3);
}
No need for other interfaces, void* etc.

Mocking using boost::shared_ptr and AMOP

I'm trying to write mocks using amop. I'm using Visual Studio 2008.
I have this interface class:
struct Interface {
virtual void Activate() = 0;
};
and this other class which receives pointers to this Interface, like this:
struct UserOfInterface {
void execute(Interface* iface) {
iface->Activate();
}
};
So I try to write some testing code like this:
amop::TMockObject<Interface> mock;
mock.Method(&Interface::Activate).Count(1);
UserOfInterface user;
user.execute((Interface*)mock);
mock.Verifiy();
It works! So far so good, but what I really want is a boost::shared_ptr in the execute() method, so I write this:
struct UserOfInterface {
void execute(boost::shared_ptr<Interface> iface) {
iface->Activate();
}
};
How should the test code be now? I tried some things, like:
amop::TMockObject<Interface> mock;
mock.Method(&Interface::Activate).Count(1);
UserOfInterface user;
boost::shared_ptr<Interface> mockAsPtr((Interface*)mock);
user.execute(mockAsPtr);
mock.Verifiy();
It compiles, but obviously crashes, since at the end of the scope the variable 'mock' gets double destroyed (because of the stack variable 'mock' and the shared_ptr).
I also tried to create the 'mock' variable on the heap:
amop::TMockObject<Interface>* mock(new amop::TMockObject<Interface>);
mock->Method(&Interface::Activate).Count(1);
UserOfInterface user;
boost::shared_ptr<Interface> mockAsPtr((Interface*)*mock);
user.execute(mockAsPtr);
mock->Verifiy();
But it doesn't work, somehow it enters an infinite loop, before I had a problem with boost not finding the destructor for the mocked object when the shared_ptr tried to delete the object.
Has anyone used amop with boost::shared_ptr successfully?
You may want to try using a more explicit cast. I'm not sure if this will work, but give it a try.
// Get the mock generator
boost::shared_ptr< amop::TMockObject<Interface> > mock
= boost::make_shared< amop::TMockObject<Interface> >;
// Get the mocked interface
boost::shared_ptr<Interface> imock = boost::dynamic_pointer_cast<Interface>(mock);
// Setup mock usage expectations
mock->Method(&Interface::Activate).Count(1);
// Run the test
UserOfInterface user;
user.execute(imock);
// Verify the expectations were met
mock->Verifiy();
Well, I never used amop, but perhaps this boost pattern will help..
To create a boost shared_ptr you can also use
boost::shared_ptr<Interface> mock(new amop::TMockObject<Interface>());
This way the mock object is not created on the stack and only destroyed if the reference counter in the shared_ptr gets to zero.
Because this is essentially the same as your second try, another tip:
If you encounter problems that look like c++ is not finding the right destructor, you might introduces a virtual destructor in the base (interface) class. Does amop allow this?
class Interface{
virtual ~Interface() { }
...
};
You can give the shared_ptr a custom functor that will be called instead of delete when the reference count goes to zero.
The code then will look like this (I didn't try to compile it):
struct NoOpDel
{
void operator() (void *) { }
}
amop::TMockObject<Interface> mock;
mock.Method(&Interface::Activate).Count(1);
UserOfInterface user;
boost::shared_ptr<Interface> imock((Interface*)mock, NoOpDel())
user.execute(imock);
mock.Verify();
See Boost API doc for more details, you are interested in this constructor:
template<class Y, class D> shared_ptr(Y * p, D d);
Disclaimer: I'm the author of HippoMocks
Using HippoMocks you can specify that you expect the destructor is called at the end of your test. It also implicitly validates your expectations at the end of your test. That way it can even guard against a stray shared_ptr on the heap that you forgot to delete or a class that doesn't take ownership or forgets to delete the pointer in the case that you don't use a shared_ptr.
There is a way to use shared_ptr with amop
struct Interface {
virtual ~Interface() {}
virtual void Activate() = 0;
};
TEST(MockObjectMethodDestructor)
{
TMockObject<Interface> mock;
mock.Method(Destructor());
boost::shared_ptr<Interface> ptr((IInterface*)mock);
ptr.reset();
}

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.