Advertisement
Guest User

Factory with commentary

a guest
Apr 18th, 2019
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.96 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement