Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <map>
- #include <vector>
- // По условию задачи мы именно так записываем его и ничего не меняем
- class Object {
- public:
- virtual std::string ToString() const = 0;
- };
- // А это уже произвольный наследник класса Object
- // Он должен иметь перегруженный метод ToString() по условию задачи
- // который будет выводить его class_id
- // Сам class_id наследник получает через конструктор
- class ChildObject : public Object {
- public:
- // Конструктор. Просто запоминает переданный class_id в переменную id
- explicit ChildObject(std::string class_id) { id = class_id; }
- // Перегруженный метод ToString. Возвращает id
- virtual std::string ToString() const { return id; }
- private:
- std::string id;
- };
- class Factory {
- public:
- Factory();
- Object* Create(const std::string& class_id);
- void Register(const std::string& class_id, Object*(*instance_creator)());
- private:
- // Мап <ключ, значение>
- // Мап используется для хранения функций создания объекта, которые будут получены через Register
- // Ключ - class_id, значение - указатель на функцию
- std::map<std::string, Object*(*)()> container_new;
- // Вектор с class_id. Он будет хранить все class_id, что нам даны изначально,
- //т.е. "apple!", "list" и "yet another identifier"
- std::vector<std::string> container_standart;
- };
- // Конструктор фабрики. Просто заполняет вектор стандартными class_id
- Factory::Factory() {
- container_standart.push_back("apple!");
- container_standart.push_back("list");
- container_standart.push_back("yet another identifier");
- }
- // Register засовывает по переданному новому class_id переданный указатель на функцию
- // instance_creator - это и есть указатель на функцию. К примеру, чтобы его использовать как обычную функцию
- // достаточно сделать так instance_creator()
- void Factory::Register(const std::string& class_id, Object*(*instance_creator)()) {
- container_new[class_id] = instance_creator;
- }
- // Create получает class_id и ищет его в одном из двух контейнеров (мапе или векторе)
- Object* Factory::Create(const std::string& class_id) {
- // Это поиск в мапе. У мапа есть стандартный метод find(ключ), который возвращает итератор на найденный объект
- // Если объекта не найдено, то возвращает итератор на конец. Нам итератор не нужен сам по себе, просто убедиться
- // что объект здесь есть
- if (container_new.find(class_id) != container_new.end()) {
- // по container_new[class_id] хранится указатель на функцию, которая вернет нам указатель на объект
- // поэтом просто вызываем ее с помощью скобочек
- return container_new[class_id]();
- }
- // поиск class_id в векторе
- for (int i = 0; i < container_standart.size(); i++) {
- // если нашли
- if (container_standart[i] == class_id) {
- // возвращаем указатель на ребенка, которому в конструктор передали class_id
- return new ChildObject(class_id);
- }
- }
- // на случай, если не найдено будет по class_id нигде
- return nullptr;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement