fork download
  1. #include <boost/shared_ptr.hpp>
  2. #include <boost/ptr_container/ptr_map.hpp>
  3. #include <iostream>
  4. #include <ostream>
  5. #include <map>
  6.  
  7. using namespace std;
  8. using namespace boost;
  9. typedef int ID;
  10.  
  11. struct SomeClass
  12. {
  13. SomeClass()
  14. {
  15. cout << "SomeClass::SomeClass()" << endl;
  16. }
  17. ~SomeClass()
  18. {
  19. cout << "SomeClass::~SomeClass()" << endl;
  20. }
  21. };
  22.  
  23. struct IVisitor
  24. {
  25. virtual void visit(int)=0;
  26. virtual void visit(double)=0;
  27. virtual void visit(SomeClass&)=0;
  28. // ..
  29. };
  30.  
  31. struct ConcreteVisitor: IVisitor
  32. {
  33. virtual void visit(int)
  34. {
  35. cout << "visiting int" << endl;
  36. }
  37. virtual void visit(double)
  38. {
  39. cout << "visiting double" << endl;
  40. }
  41. virtual void visit(SomeClass&)
  42. {
  43. cout << "visiting SomeClass" << endl;
  44. }
  45. // ..
  46. };
  47.  
  48. struct ITypeStorage
  49. {
  50. virtual void apply_visitor(void *obj,IVisitor &visitor)=0;
  51. };
  52.  
  53. template<typename ObjectType> struct TypeStorage: ITypeStorage
  54. {
  55. virtual void apply_visitor(void *obj,IVisitor &visitor)
  56. {
  57. visitor.visit( *(static_cast<ObjectType *>(obj)) );
  58. }
  59. };
  60.  
  61. class ObjectManager
  62. {
  63. map<ID,boost::shared_ptr<void> > objects;
  64. ptr_map<ID,ITypeStorage> types;
  65. public:
  66. template <class T>
  67. void create_object(ID id)
  68. {
  69. objects[id].reset(new T());//shared_ptr will use right deleter
  70. types.insert(id,new TypeStorage<T>());
  71. }
  72. void apply(ID id,IVisitor &visitor)
  73. {
  74. types.find(id)->second->apply_visitor(objects[id].get(),visitor);
  75. }
  76. };
  77.  
  78. int main(int argc,char *argv[])
  79. {
  80. ObjectManager manager;
  81. ConcreteVisitor visitor;
  82.  
  83. manager.create_object<int>(1);
  84. manager.create_object<double>(2);
  85. manager.create_object<SomeClass>(3);
  86.  
  87. manager.apply(1,visitor);
  88. manager.apply(2,visitor);
  89. manager.apply(3,visitor);
  90. return 0;
  91. }
  92.  
Success #stdin #stdout 0.01s 2824KB
stdin
Standard input is empty
stdout
SomeClass::SomeClass()
visiting int
visiting double
visiting SomeClass
SomeClass::~SomeClass()