SHARE
TWEET

Factory with commentary

a guest Apr 18th, 2019 83 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <string>
  2. #include <map>
  3. #include <vector>
  4.  
  5. // По условию задачи мы именно так записываем его и ничего не меняем
  6. class Object {
  7.  public:
  8.     virtual std::string ToString() const = 0;
  9. };
  10.  
  11. // А это уже произвольный наследник класса Object
  12. // Он должен иметь перегруженный метод ToString() по условию задачи
  13. // который будет выводить его class_id
  14. // Сам class_id наследник получает через конструктор
  15. class ChildObject : public Object {
  16.  public:
  17.     // Конструктор. Просто запоминает переданный class_id в переменную id
  18.     explicit ChildObject(std::string class_id) { id = class_id; }
  19.     // Перегруженный метод ToString. Возвращает id
  20.     virtual std::string ToString() const { return id; }
  21.  private:
  22.     std::string id;
  23. };
  24.  
  25. class Factory {
  26.  public:
  27.     Factory();
  28.     Object* Create(const std::string& class_id);
  29.     void Register(const std::string& class_id, Object*(*instance_creator)());
  30.  private:
  31.     // Мап <ключ, значение>
  32.     // Мап используется для хранения функций создания объекта, которые будут получены через Register
  33.     // Ключ - class_id, значение - указатель на функцию
  34.     std::map<std::string, Object*(*)()> container_new;
  35.  
  36.     // Вектор с class_id. Он будет хранить все class_id, что нам даны изначально,
  37.     //т.е. "apple!", "list" и "yet another identifier"
  38.     std::vector<std::string> container_standart;
  39. };
  40.  
  41. // Конструктор фабрики. Просто заполняет вектор стандартными class_id
  42. Factory::Factory() {
  43.     container_standart.push_back("apple!");
  44.     container_standart.push_back("list");
  45.     container_standart.push_back("yet another identifier");
  46. }
  47.  
  48. // Register засовывает по переданному новому class_id переданный указатель на функцию
  49. // instance_creator - это и есть указатель на функцию. К примеру, чтобы его использовать как обычную функцию
  50. // достаточно сделать так instance_creator()
  51. void Factory::Register(const std::string& class_id, Object*(*instance_creator)()) {
  52.     container_new[class_id] = instance_creator;
  53. }
  54.  
  55. // Create получает class_id и ищет его в одном из двух контейнеров (мапе или векторе)
  56. Object* Factory::Create(const std::string& class_id) {
  57.     // Это поиск в мапе. У мапа есть стандартный метод find(ключ), который возвращает итератор на найденный объект
  58.     // Если объекта не найдено, то возвращает итератор на конец. Нам итератор не нужен сам по себе, просто убедиться
  59.     // что объект здесь есть
  60.     if (container_new.find(class_id) != container_new.end()) {
  61.         // по container_new[class_id] хранится указатель на функцию, которая вернет нам указатель на объект
  62.         // поэтом просто вызываем ее с помощью скобочек
  63.         return container_new[class_id]();
  64.     }
  65.  
  66.     // поиск class_id в векторе
  67.     for (int i = 0; i < container_standart.size(); i++) {
  68.         // если нашли
  69.         if (container_standart[i] == class_id) {
  70.             // возвращаем указатель на ребенка, которому в конструктор передали class_id
  71.             return new ChildObject(class_id);
  72.         }
  73.     }
  74.     // на случай, если не найдено будет по class_id нигде
  75.     return nullptr;
  76. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top