#include #include #include #include #include #include using std::map; using std::string; using std::cout; using std::cin; using std::vector; using std::endl; using std::runtime_error; class Object { public: virtual string ToString() const = 0; virtual ~Object() = default; }; class Apple : public Object { public: string ToString() const override { return "apple!"; } }; class List : public Object { public: string ToString() const override { return "list"; } }; class YetAnotherId : public Object { public: string ToString() const override { return "yet another identifier"; } }; map registered_classes; class Smth : public Object { public: explicit Smth(const string &class_id) { class_id_ = class_id; } string ToString() const override { return class_id_; } private: string class_id_; }; Object *anyCreator_() { return new Smth("plug"); } class Factory { public: static Object *Create(const string &class_id) { if (class_id == "apple") { return new Apple; } else if (class_id == "list") { return new List; } else if (class_id == "yet another identifier") { return new YetAnotherId; } else { if (registered_classes.count(class_id) > 0) { return new Smth(class_id); } else throw runtime_error("not registered"); } } static void Register(const string &class_id, Object *(*creator)()) { registered_classes[class_id] = creator; } }; int main() { string class_id; getline(cin, class_id); string a = "apple", b = "list", c = "yet another identifier"; try { if (class_id != a && class_id != b && class_id != c) { Factory::Register(class_id, anyCreator_); } Object *heir = Factory::Create(class_id); cout << heir->ToString() << endl; delete heir; } catch (runtime_error &e) { cout << e.what() << endl; } }