Advertisement
kutuzzzov

Урок 2 Умный указатель

Mar 28th, 2023
1,121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.82 KB | None | 0 0
  1. #include <cassert>
  2. #include <iostream>
  3. #include <memory>
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8. struct Cat {
  9.     Cat(const string& name, int age)
  10.         : name_(name)
  11.         , age_(age)  //
  12.     {
  13.     }
  14.     const string& GetName() const noexcept {
  15.         return name_;
  16.     }
  17.     int GetAge() const noexcept {
  18.         return age_;
  19.     }
  20.     ~Cat() {
  21.     }
  22.     void Speak() const {
  23.         cout << "Meow!"s << endl;
  24.     }
  25.  
  26. private:
  27.     string name_;
  28.     int age_;
  29. };
  30.  
  31. // Функция создаёт двухлетних котов
  32. unique_ptr<Cat> CreateCat(const string& name) {
  33.     return make_unique<Cat>(name, 2);
  34. }
  35.  
  36. class Witch {
  37. public:
  38.     explicit Witch(const string& name)
  39.         : name_(name) {
  40.     }
  41.    
  42.     Witch(const Witch& other) {
  43.         name_ = other.name_;
  44.         cat_ = make_unique<Cat>(other.cat_->GetName(), other.cat_->GetAge());
  45.     }
  46.  
  47.     Witch operator=(Witch& other) {
  48.         auto temp_name = other.name_;
  49.         auto temp_cat = make_unique<Cat>(other.cat_->GetName(), other.cat_->GetAge());
  50.         swap(temp_name, name_);
  51.         swap(temp_cat, cat_);
  52.         return *this;
  53.     }
  54.    
  55.     Witch(Witch&&) = default;
  56.     Witch& operator=(Witch&&) = default;
  57.  
  58.     const string& GetName() const noexcept {
  59.         return name_;
  60.     }
  61.     void SetCat(unique_ptr<Cat>&& cat) noexcept {
  62.         cat_ = std::move(cat);
  63.     }
  64.     unique_ptr<Cat> ReleaseCat() noexcept {
  65.         return std::move(cat_);
  66.     }
  67.  
  68. private:
  69.     string name_;
  70.     unique_ptr<Cat> cat_;
  71. };
  72.  
  73. void Test() {
  74.     // Объекты Witch можно перемещать
  75.     {
  76.         Witch witch("Hermione"s);
  77.         auto cat = CreateCat("Crookshanks"s);
  78.         Cat* raw_cat = cat.get();
  79.         assert(raw_cat);
  80.         witch.SetCat(move(cat));
  81.  
  82.         Witch moved_witch(std::move(witch));
  83.         auto released_cat = moved_witch.ReleaseCat();
  84.         assert(released_cat.get() == raw_cat);  // Кот переместился от witch к moved_witch
  85.     }
  86.  
  87.     // Можно использовать перемещающий оператор присваивания
  88.     {
  89.         Witch witch("Hermione"s);
  90.         auto cat = CreateCat("Crookshanks"s);
  91.         Cat* raw_cat = cat.get();
  92.         witch.SetCat(move(cat));
  93.  
  94.         Witch witch2("Minerva McGonagall");
  95.         witch2 = move(witch);
  96.         auto released_cat = witch.ReleaseCat();
  97.         assert(!released_cat);
  98.         released_cat = witch2.ReleaseCat();
  99.         assert(released_cat.get() == raw_cat);
  100.     }
  101.  
  102.     // Можно копировать волшебниц
  103.     {
  104.         Witch witch("Hermione");
  105.         auto cat = CreateCat("Crookshanks"s);
  106.         witch.SetCat(move(cat));
  107.  
  108.         Witch witch_copy(witch);
  109.         assert(!cat);
  110.         cat = witch.ReleaseCat();
  111.         assert(cat);  // У первой волшебницы кот никуда не делся
  112.  
  113.         auto cat_copy = witch_copy.ReleaseCat();
  114.         assert(cat_copy != nullptr && cat_copy != cat);
  115.         assert(cat_copy->GetName() == cat->GetName());  // Копия волшебницы содержит копию кота
  116.     }
  117.  
  118.     // Работает копирующее присваивание волшебниц
  119.     {
  120.         Witch witch("Hermione"s);
  121.         auto cat = CreateCat("Crookshanks"s);
  122.         witch.SetCat(move(cat));
  123.  
  124.         Witch witch2("Minerva McGonagall"s);
  125.         witch2 = witch;
  126.  
  127.         assert(!cat);
  128.         cat = witch.ReleaseCat();
  129.         assert(cat);  // У первой волшебницы кот никуда не делся
  130.  
  131.         auto cat_copy = witch2.ReleaseCat();
  132.         assert(cat_copy != nullptr && cat_copy != cat);
  133.         assert(cat_copy->GetName() == cat->GetName());  // При присваивании скопировался кот
  134.     }
  135. }
  136.  
  137. int main() {
  138.     Test();
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement