多态工厂
思考:
注册类的时候仍然是需要手动添加到初始化类中,有没有办法通过传递类名,或者以类字符串的形式注册新类?
#include <iostream> #include <map> #include <string> #include <vector> #include <stdexcept> #include <cstddef> //#include "../purge.h" using namespace std; class Shape { public: virtual void draw() = 0; virtual void erase() = 0; virtual ~Shape() {} }; //base class class ShapeFactory { private: virtual Shape* create() = 0; // <类名称--该类的创建工厂> static map<string, ShapeFactory*> factories; public: virtual ~ShapeFactory() {} friend class ShapeFactoryInitializer; class BadShapeCreation : public logic_error { public: BadShapeCreation(string type) : logic_error("Cannot create type " + type) {} }; // 通过类名称找到类的创建工厂,调用create()方法对象 static Shape* createShape(const string& id) throw(BadShapeCreation) { if(factories.find(id) != factories.end()) return factories[id]->create(); else throw BadShapeCreation(id); } }; // Define the static object: map<string, ShapeFactory*> ShapeFactory::factories; class Circle : public Shape { private: Circle() { } // Private constructor friend class ShapeFactoryInitializer; // 当前类的创建工厂,实际上就是为了封装create方法,即“方法对象” class Factory : public ShapeFactory { public: // 实现当前对象的创建 Shape* create() { return new Circle; } // 这一句似乎没多大意义,除非将将Facotry()设为私有 friend class ShapeFactoryInitializer; }; public: void draw() { cout << "Circle::draw" << endl; } void erase() { cout << "Circle::erase" << endl; } ~Circle() { cout << "Circle::~Circle" << endl; } }; class Square : public Shape { Square() {} // Private constructor friend class ShapeFactoryInitializer; class Factory : public ShapeFactory { public: Shape* create() { return new Square; } friend class ShapeFactoryInitializer; }; public: void draw() { cout << "Square::draw" << endl; } void erase() { cout << "Square::erase" << endl; } ~Square() { cout << "Square::~Square" << endl; } }; //单例模式 class ShapeFactoryInitializer { private: static ShapeFactoryInitializer si; ShapeFactoryInitializer() { ShapeFactory::factories["Circle"]= new Circle::Factory; ShapeFactory::factories["Square"]= new Square::Factory; } ~ShapeFactoryInitializer() { map<string, ShapeFactory*>::iterator it = ShapeFactory::factories.begin(); while(it != ShapeFactory::factories.end()) delete it++->second; } }; ShapeFactoryInitializer ShapeFactoryInitializer::si; int main() { try { Shape *circle_s = ShapeFactory::createShape("Circle"); circle_s->draw(); circle_s->erase(); } catch(ShapeFactory::BadShapeCreation e) { cout << e.what() << endl; return EXIT_FAILURE; } return 0; }