
All, Again thank you Steven for your great suggestion, though I have compiler problems, using 1.38, 1.37, and even 1.33.1. I am putting my code here so maybe I am missing something simple. Thank you, Victor =====code starts here======= // for thread-safe singleton #include <boost/utility.hpp> #include <boost/thread/once.hpp> #include <boost/scoped_ptr.hpp> // for the factory #include <string> #include <map> #include <boost/shared_ptr.hpp> #include <boost/thread/mutex.hpp> #include <boost/function.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/construct.hpp> // for the main test #include <assert.h> #include <iostream> #include <vector> //////////////////////////////////////////////////////////////////////////////// // thread-safe singleton from http://www.boostcookbook.com/Recipe:/1235044 //////////////////////////////////////////////////////////////////////////////// template<class T> class Singleton : private boost::noncopyable { public: static T& instance() { boost::call_once(init, flag); return *t; } static void init() { t.reset(new T()); } protected: ~Singleton() {} Singleton() {} private: static boost::scoped_ptr<T> t; static boost::once_flag flag; }; template<class T> boost::scoped_ptr<T> Singleton<T>::t(0); template<class T> boost::once_flag Singleton<T>::flag = BOOST_ONCE_INIT; //////////////////////////////////////////////////////////////////////////////// // generic factory //////////////////////////////////////////////////////////////////////////////// template<typename BaseType,typename KeyType> class GenericFactory: public Singleton<GenericFactory<BaseType,KeyType> > { friend class Singleton<GenericFactory<BaseType,KeyType> >; typedef std::map<KeyType, boost::function<BaseType*()> > TypeMap_t; public: GenericFactory() { } ~GenericFactory() {} boost::shared_ptr<BaseType> create(const KeyType& typeName) { boost::mutex::scoped_lock lock(m_mutex); boost::shared_ptr<BaseType> answer; if ( m_creators.end() != m_creators.find(typeName) ) { answer.reset( m_creators[typeName]() ); } return answer; } template<typename DerivedType> inline void registrator(const KeyType& _key) { boost::mutex::scoped_lock lock(m_mutex); typename TypeMap_t::const_iterator i = m_creators.find(_key); if ( m_creators.end() == i ) { m_creators[ _key ] = boost::lambda::new_ptr<DerivedType>(); } } protected: TypeMap_t m_creators; mutable boost::mutex m_mutex; }; template <typename BaseType, typename KeyType, typename DerivedType> struct RegisterDerived { RegisterDerived(const KeyType& _key) { GenericFactory<BaseType,KeyType>::instance().registrator<DerivedType>(_key); } }; //////////////////////////////////////////////////////////////////////////////// // a simple base class //////////////////////////////////////////////////////////////////////////////// class Base { public: Base() { } virtual ~Base() { } Base(const Base& rhs) { } Base& operator=(const Base& rhs) { if (&rhs != this) { ; } return *this; } virtual const std::string typeName() const=0; }; //////////////////////////////////////////////////////////////////////////////// // a Factory for our classes derived from Base //////////////////////////////////////////////////////////////////////////////// typedef GenericFactory<Base,std::string> FooFactory; //////////////////////////////////////////////////////////////////////////////// // derived class A //////////////////////////////////////////////////////////////////////////////// class A: public Base { public: A() : Base() { } A(const A& rhs) : Base(rhs) { } A& operator=(const A& rhs) { if (&rhs != this) { (Base&)*this = rhs; } return *this; } virtual ~A() { } virtual const std::string typeName() const { return "a"; } }; // attempt to register the derived classes with the factory RegisterDerived<Base,std::string,A> myARegistrar(std::string("a")); //////////////////////////////////////////////////////////////////////////////// // derived class B //////////////////////////////////////////////////////////////////////////////// class B: public Base { public: B() : Base() { } B(const B& rhs) : Base(rhs) { } B& operator=(const B& rhs) { if (&rhs != this) { (Base&)*this = rhs; } return *this; } virtual ~B() { } virtual const std::string typeName() const { return "b"; } }; // attempt to register the derived classes with the factory RegisterDerived<Base,std::string,B> myBRegistrar(std::string("b")); //////////////////////////////////////////////////////////////////////////////// // a simple test //////////////////////////////////////////////////////////////////////////////// int main() { typedef boost::shared_ptr<Base> BasePtr; typedef std::vector< BasePtr > BaseList; { // try to create a classifier using an unregistered (i.e. unknown) typeName BasePtr myPtr = FooFactory::instance().create("Z"); assert ( NULL == myPtr ); } { // try to create a derived class using its valid registered typeName BasePtr myPtr = FooFactory::instance().create("a"); assert ( NULL != myPtr); assert ( myPtr->typeName() == "a" ); } { // try to create a different derived class using a valid registered typeName BasePtr myPtr = FooFactory::instance().create("b"); assert ( NULL != myPtr); assert ( myPtr->typeName() == "b" ); } BaseList myList; myList.push_back( FooFactory::instance().create("a") ); myList.push_back( FooFactory::instance().create("b") ); for ( BaseList::iterator i= myList.begin(); i != myList.end(); ++i) { std::cerr<<"The typename is "<<(*i)->typeName()<<std::endl; } return 0; } =====code ends here=======