#include <boost/shared_ptr.hpp>
#include <boost/ptr_container/ptr_map.hpp>
#include <iostream>
#include <ostream>
#include <map>
using namespace std;
using namespace boost;
typedef int ID;
struct SomeClass
{
SomeClass()
{
cout << "SomeClass::SomeClass()" << endl;
}
~SomeClass()
{
cout << "SomeClass::~SomeClass()" << endl;
}
};
struct IVisitor
{
virtual void visit(int)=0;
virtual void visit(double)=0;
virtual void visit(SomeClass&)=0;
// ..
};
struct ConcreteVisitor: IVisitor
{
virtual void visit(int)
{
cout << "visiting int" << endl;
}
virtual void visit(double)
{
cout << "visiting double" << endl;
}
virtual void visit(SomeClass&)
{
cout << "visiting SomeClass" << endl;
}
// ..
};
struct ITypeStorage
{
virtual void apply_visitor(void *obj,IVisitor &visitor)=0;
};
template<typename ObjectType> struct TypeStorage: ITypeStorage
{
virtual void apply_visitor(void *obj,IVisitor &visitor)
{
visitor.visit( *(static_cast<ObjectType *>(obj)) );
}
};
class ObjectManager
{
map<ID,boost::shared_ptr<void> > objects;
ptr_map<ID,ITypeStorage> types;
public:
template <class T>
void create_object(ID id)
{
objects[id].reset(new T());//shared_ptr will use right deleter
types.insert(id,new TypeStorage<T>());
}
void apply(ID id,IVisitor &visitor)
{
types.find(id)->second->apply_visitor(objects[id].get(),visitor);
}
};
int main(int argc,char *argv[])
{
ObjectManager manager;
ConcreteVisitor visitor;
manager.create_object<int>(1);
manager.create_object<double>(2);
manager.create_object<SomeClass>(3);
manager.apply(1,visitor);
manager.apply(2,visitor);
manager.apply(3,visitor);
return 0;
}