shizaero

Untitled

Jul 1st, 2023
266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.91 KB | None | 0 0
  1. #pragma once
  2. #include "scopedptr.h"
  3. #include "ptrvector.h"
  4. #include <new> // Для исключения bad_alloc
  5. #include <vector>
  6.  
  7. // Щупальце
  8. class Tentacle {
  9. public:
  10.     explicit Tentacle(int id) noexcept
  11.         : id_(id) {
  12.     }
  13.  
  14.     int GetId() const noexcept {
  15.         return id_;
  16.     }
  17.  
  18.     Tentacle* GetLinkedTentacle() const noexcept {
  19.         return linked_tentacle_;
  20.     }
  21.     void LinkTo(Tentacle& tentacle) noexcept {
  22.         linked_tentacle_ = &tentacle;
  23.     }
  24.     void Unlink() noexcept {
  25.         linked_tentacle_ = nullptr;
  26.     }
  27.  
  28. private:
  29.     int id_ = 0;
  30.     Tentacle* linked_tentacle_ = nullptr;
  31. };
  32.  
  33. // Осьминог
  34. class Octopus {
  35. public:
  36.     Octopus()
  37.         : Octopus(8) {
  38.     }
  39.  
  40.     explicit Octopus(int num_tentacles) {
  41.         Tentacle* t = nullptr;
  42.         try {
  43.             for (int i = 1; i <= num_tentacles; ++i) {
  44.                 t = new Tentacle(i);      // Может выбросить исключение bad_alloc
  45.                 tentacles_.GetItems().push_back(t);  // Может выбросить исключение bad_alloc
  46.  
  47.                 // Обнуляем указатель на щупальце, которое уже добавили в tentacles_,
  48.                 // чтобы не удалить его в обработчике catch повторно
  49.                 t = nullptr;
  50.             }
  51.         } catch (const std::bad_alloc&) {
  52.             // Удаляем щупальца, которые успели попасть в контейнер tentacles_
  53.             Cleanup();
  54.             // Удаляем щупальце, которое создали, но не добавили в tentacles_
  55.             delete t;
  56.             // Конструктор не смог создать осьминога с восемью щупальцами,
  57.             // поэтому выбрасываем исключение, чтобы сообщить вызывающему коду об ошибке
  58.             // throw без параметров внутри catch выполняет ПЕРЕВЫБРОС пойманного исключения
  59.             throw;
  60.         }
  61.     }
  62.  
  63.     ~Octopus() {
  64.         // Осьминог владеет объектами в динамической памяти (щупальца),
  65.         // которые должны быть удалены при его разрушении.
  66.         // Деструктор - лучшее место, чтобы прибраться за собой.
  67.         Cleanup();
  68.     }
  69.  
  70.     // Добавляет новое щупальце с идентификатором,
  71.     // равным (количество_щупалец + 1):
  72.     // 1, 2, 3, ...
  73.     // Возвращает ссылку на добавленное щупальце
  74.    
  75.     Tentacle& AddTentacle() {
  76.         int id = tentacles_.GetItems().back().GetId(); // получение id
  77.         Tentacle& tentacle(id+1); //создание щупальца
  78.         tentacles_.GetItems().push_back(tentacle); //добавление щупальца
  79.         return tentacle;
  80.     }
  81.  
  82.     int GetTentacleCount() const noexcept {
  83.         return static_cast<int>(tentacles_.size());
  84.     }
  85.  
  86.     const Tentacle& GetTentacle(size_t index) const {
  87.         return *tentacles_.at(index);
  88.     }
  89.     Tentacle& GetTentacle(size_t index) {
  90.         return *tentacles_.at(index);
  91.     }
  92.  
  93. private:
  94.     void Cleanup() {
  95.         // Удаляем щупальца осьминога из динамической памяти
  96.         for (Tentacle* t : tentacles_) {
  97.             delete t;
  98.         }
  99.         // Очищаем массив указателей на щупальца
  100.         tentacles_.clear();
  101.     }
  102.  
  103.     // Вектор хранит указатели на щупальца. Сами объекты щупалец находятся в куче
  104.     PtrVector<Tentacle*> tentacles_;
  105. };
Advertisement
Add Comment
Please, Sign In to add comment