// Copyright (c) 2000 Stuart McConnell // // stuart_mcconnell@mail.com // #if defined ( WIN32 ) #pragma warning ( disable : 4786 ) #endif #include #include #include using namespace std; // template based factory template class factory { public: typedef typename T base_type; class creator_base { public: base_type* operator()() { return create(); } virtual base_type* create() const = 0; }; template class creator : public creator_base { public: typedef typename D derived_type; virtual base_type* create() const { return new derived_type(); } }; typedef std::map string_creator_map; void register_object( const std::string& classname, creator_base* creator ) { string_creator_map::iterator iter = _classes.find( classname ); if ( iter == _classes.end() ) { _classes[classname] = creator; } } base_type* create_object( const std::string& classname ) { base_type* obj = 0; string_creator_map::iterator iter = _classes.find( classname ); if ( iter != _classes.end() ) { obj = (*(*iter).second)(); } return obj; } protected: string_creator_map _classes; }; // sample test program with an example object hierarchy class object {}; class game_object : public object {}; class light_object : public object {}; // create an instance of a factory for 'object' derived classes static factory f; // simple wrapper for creating an object object* create( const std::string& classname ) { object* obj = f.create_object( classname ); cout << "create_object(" << classname << ")\t:\t" << ( (obj) ? "successful" : "failed") << endl << endl; return obj; } int main( int argc, char* argv[] ) { // register the sample derived objects f.register_object( "game_object", new factory::creator() ); f.register_object( "light_object", new factory::creator() ); // try to create instances of the objects object* game = create( "game_object" ); object* light = create( "light_object" ); object* other = create( "other_object" ); // cleanup delete game; delete light; delete other; return 0; }