
PROBLEM: How to use Boost shared_ptr for returning the new Component object from an object factory? DESCRIPTION: I have a class which is acting as a factory for all the components in a system. The problem is that this class is getting large and I am concerned about its future growth. My idea is to switch to using an object factory which has a map of registered components. The creation code for each component will be inside the class rather than in this factory class. #ifndef COMPONENT_FACTORY_H_ #define COMPONENT_FACTORY_H_ #include <boost/shared_ptr.hpp> #include "libreverse/infrastructure/Component_Types.h" namespace produce { namespace infrastructure { class Component_Factory { public: static Component_Factory& Instance(); infrastructure_types::Component::ptr_t get_Apple ( boost::uint32_t id ); infrastructure_types::Component::ptr_t get_Berry ( boost::uint32_t id ); infrastructure_types::Component::ptr_t get_Carrot ( boost::uint32_t id ); private: Component_Factory (){} Component_Factory ( const Component_Factory& ); Component_Factory& operator = ( const Component_Factory& ); ~Component_Factory (){} }; } /* namespace infrastructure */ } /* namespace produce */ #endif /* COMPONENT_FACTORY_H_ */ If I keep this up I will have a ton of functions for creating each type of fruit or vegatable. So I would rather not have this. So I went for an object factory that I saw in Alexandrescu's Modern C++ Design: #include <map> #include <iostream> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> #include <boost/function.hpp> namespace tool { namespace component { class Component {}; class Apple : public Component { public: static const int ID = 1; static Component* Create() { return new Apple; } }; class Blueberry : public Component { public: static const int ID = 5; static Component* Create() { return new Blueberry; } }; } namespace infrastructure { class Component_Factory { public: typedef component::Component* (*CreateComponentCallback)(); static Component_Factory& Instance() { static Component_Factory obj; return obj; } bool RegisterComponent ( int component_id, CreateComponentCallback call_func ) { return m_callbacks.insert ( CallbackMap::value_type ( component_id, call_func ) ).second; } bool UnregisterComponent ( int component_id ) { return m_callbacks.erase ( component_id ) == 1; } component::Component* CreateComponent ( int component_id ) { CallbackMap::const_iterator pos = m_callbacks.find ( component_id ); if ( pos == m_callbacks.end() ) { std::cerr << "Unknown Component ID" << std::endl; abort(); } return (pos->second)(); } private: typedef std::map<int, CreateComponentCallback> CallbackMap; CallbackMap m_callbacks; Component_Factory() { this->RegisterComponent ( tool::component::Apple::ID, &tool::component::Apple::Create ); this->RegisterComponent ( tool::component::Blueberry::ID, &tool::component::Blueberry::Create ); } Component_Factory ( Component_Factory const& rhs ); Component_Factory& operator= ( Component_Factory const& rhs ); ~Component_Factory(){} }; } } In this example the many factory functions to create a type are replaced by one function. The code to create the object is placed in a function in the object's class. That way the object is responsible for creating a copy of itself. The problem is that I am not sure how to use the boost shared pointer here. I have no problem changing the Component* places to have a boost::shared_ptr<Component>. Its the callback function signature that has me stumped. typedef component::Component* (*CreateComponentCallback)(); Do I simply do: typedef boost::shared_ptr<component::Component> (*CreateComponentCallback)(); What about the callback function? Can I replace that with the operator() in each of the classes so that I can replace the static Create function? I would like to make a purely virtual function in the Component class that requires the child class to have the operator() function for creating a new instance of the child class. This is more than enough to get started. I hope I have been clear. If not please ask me questions. Stephen