Advertisement
chevengur

СПРИНТ № 7 | Модель памяти в C++ | Урок 7: Копирование объектов. Часть первая

Apr 19th, 2024
665
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.56 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5.  
  6.  
  7. using namespace std;
  8.  
  9. // Щупальце
  10. class Tentacle {
  11. public:
  12.     explicit Tentacle(int id)
  13.             : id_(id) {
  14.     }
  15.  
  16.     int GetId() const {
  17.         return id_;
  18.     }
  19.  
  20. private:
  21.     int id_ = 0;
  22. };
  23.  
  24. // Осьминог
  25. class Octopus {
  26. public:
  27.     Octopus() {
  28.         Tentacle* t = nullptr;
  29.         try {
  30.             for (int i = 1; i <= 8; ++i) {
  31.                 t = new Tentacle(i);      // Может выбросить исключение bad_alloc
  32.                 tentacles_.push_back(t);  // Может выбросить исключение bad_alloc
  33.  
  34.                 // Обнуляем указатель на щупальце, которое уже добавили в tentacles_,
  35.                 // чтобы не удалить его в обработчике catch повторно
  36.                 t = nullptr;
  37.             }
  38.         } catch (const bad_alloc&) {
  39.             // Удаляем щупальца, которые успели попасть в контейнер tentacles_
  40.             Cleanup();
  41.             // Удаляем щупальце, которое создали, но не добавили в tentacles_
  42.             delete t;
  43.             // Конструктор не смог создать осьминога с восемью щупальцами,
  44.             // поэтому выбрасываем исключение, чтобы сообщить вызывающему коду об ошибке
  45.             // throw без параметров внутри catch выполняет ПЕРЕВЫБРОС пойманного исключения
  46.             throw;
  47.         }
  48.     }
  49.  
  50.     const Tentacle& GetTentacle(int index) const {
  51.         if (index < 0 || static_cast<size_t>(index) >= tentacles_.size()) {
  52.             throw out_of_range("Invalid tentacle index"s);
  53.         }
  54.         // Чтобы превратить указатель в ссылку, разыменовываем его
  55.         return *tentacles_[index];
  56.     }
  57.  
  58.     ~Octopus() {
  59.         // Осьминог владеет объектами в динамической памяти (щупальца),
  60.         // которые должны быть удалены при его разрушении.
  61.         // Деструктор - лучшее место, чтобы прибраться за собой.
  62.         Cleanup();
  63.     }
  64.  
  65. private:
  66.     void Cleanup() {
  67.         // Удаляем щупальца осьминога из динамической памяти
  68.         for (Tentacle* t : tentacles_) {
  69.             delete t;
  70.         }
  71.         // Очищаем массив указателей на щупальца
  72.         tentacles_.clear();
  73.     }
  74.  
  75.     // Вектор хранит указатели на щупальца. Сами объекты щупалец находятся в куче
  76.     vector<Tentacle*> tentacles_;
  77. };
  78.  
  79. int main() {
  80.     // Один из множества способов вызвать неопределённое поведение
  81.     for (int i = 1; i <= 1000; ++i) {
  82.         Octopus octopus;
  83.         cout << "Copying octopus "s << i << " " << octopus.GetTentacle(0).GetId() << endl;
  84.         Octopus octopus_copy0(octopus);
  85. //        Octopus octopus_copy1(octopus);
  86.         // octopus_copy1, octopus_copy0 и octopus оторвут щупальца друг другу
  87.     }
  88.     // Возможно, эта надпись не будет выведена
  89.     cout << "Congratulations, everything is ok"s << endl;
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement