shushus

Спринт 7. Присваивание объектов. Задание 1.

Jan 12th, 2023
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.11 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <stdexcept>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. template <typename T>
  9. class PtrVector {
  10. public:
  11.     PtrVector() = default;
  12.  
  13.     PtrVector(const PtrVector& other) {
  14.         items_.reserve(other.items_.size());
  15.         try {
  16.             for (auto p : other.items_) {
  17.                 auto p_copy = p ? new T(*p) : nullptr;
  18.  
  19.                 items_.push_back(p_copy);
  20.             }
  21.         } catch (...) {
  22.             DeleteItems();
  23.             throw;
  24.         }
  25.     }
  26.    
  27.     PtrVector& operator=(const PtrVector& rhs) {
  28.         if (this != &rhs) {
  29.             auto rhs_copy(rhs);
  30.             items_.swap(rhs_copy.items_);
  31.         }
  32.         return *this;
  33.     }
  34.  
  35.     void swap(PtrVector& other) noexcept;
  36.  
  37.     ~PtrVector() {
  38.         DeleteItems();
  39.     }
  40.  
  41.     vector<T*>& GetItems() noexcept {
  42.         return items_;
  43.     }
  44.  
  45.     vector<T*> const& GetItems() const noexcept {
  46.         return items_;
  47.     }
  48.  
  49. private:
  50.     void DeleteItems() noexcept {
  51.         for (auto p : items_) {
  52.             delete p;
  53.         }
  54.     }
  55.  
  56.     vector<T*> items_;
  57. };
  58.  
  59. int main() {
  60.     struct CopyingSpy {
  61.         CopyingSpy(int& copy_count, int& deletion_count)
  62.             : copy_count_(copy_count)
  63.             , deletion_count_(deletion_count) {
  64.         }
  65.         CopyingSpy(const CopyingSpy& rhs)
  66.             : copy_count_(rhs.copy_count_)
  67.             , deletion_count_(rhs.deletion_count_)  
  68.         {
  69.             if (rhs.throw_on_copy_) {
  70.                 throw runtime_error("copy construction failed"s);
  71.             }
  72.             ++copy_count_;
  73.         }
  74.         ~CopyingSpy() {
  75.             ++deletion_count_;
  76.         }
  77.         void ThrowOnCopy() {
  78.             throw_on_copy_ = true;
  79.         }
  80.  
  81.     private:
  82.         int& copy_count_;
  83.         int& deletion_count_;
  84.         bool throw_on_copy_ = false;
  85.     };
  86.  
  87.     {
  88.         int item0_copy_count = 0;
  89.         int item0_deletion_count = 0;
  90.         {
  91.             PtrVector<CopyingSpy> v;
  92.  
  93.             v.GetItems().push_back(new CopyingSpy(item0_copy_count, item0_deletion_count));
  94.             v.GetItems().push_back(nullptr);
  95.             {
  96.                 PtrVector<CopyingSpy> v_copy;
  97.                 v_copy = v;
  98.                 assert(v_copy.GetItems().size() == v.GetItems().size());
  99.                 assert(v_copy.GetItems().at(0) != v.GetItems().at(0));
  100.                 assert(v_copy.GetItems().at(1) == nullptr);
  101.                 assert(item0_copy_count == 1);
  102.                 assert(item0_deletion_count == 0);
  103.             }
  104.             assert(item0_deletion_count == 1);
  105.         }
  106.         assert(item0_deletion_count == 2);
  107.     }
  108.  
  109.     {
  110.         int item0_copy_count = 0;
  111.         int item0_deletion_count = 0;
  112.  
  113.         PtrVector<CopyingSpy> v;
  114.         v.GetItems().push_back(new CopyingSpy(item0_copy_count, item0_deletion_count));
  115.         CopyingSpy* first_item = v.GetItems().front();
  116.  
  117.         v = v;
  118.         assert(v.GetItems().size() == 1);
  119.         assert(v.GetItems().front() == first_item);
  120.         assert(item0_copy_count == 0);
  121.         assert(item0_deletion_count == 0);
  122.     }
  123.  
  124.     {
  125.         int item0_copy_count = 0;
  126.         int item0_deletion_count = 0;
  127.  
  128.         int item1_copy_count = 0;
  129.         int item1_deletion_count = 0;
  130.  
  131.         PtrVector<CopyingSpy> v;
  132.         v.GetItems().push_back(new CopyingSpy(item0_copy_count, item0_deletion_count));
  133.         v.GetItems().push_back(new CopyingSpy(item1_copy_count, item1_deletion_count));
  134.  
  135.         int other_item0_copy_count = 0;
  136.         int other_item0_deletion_count = 0;
  137.         PtrVector<CopyingSpy> other_vector;
  138.         other_vector.GetItems().push_back(new CopyingSpy(other_item0_copy_count, other_item0_deletion_count));
  139.         other_vector.GetItems().front()->ThrowOnCopy();
  140.  
  141.         auto v_items(v.GetItems());
  142.  
  143.         try {
  144.             v = other_vector;
  145.             assert(false);
  146.         } catch (const runtime_error&) {
  147.         }
  148.  
  149.         assert(v.GetItems() == v_items);
  150.         assert(item0_copy_count == 0);
  151.         assert(item1_copy_count == 0);
  152.         assert(other_item0_copy_count == 0);
  153.     }
  154. }
Advertisement
Add Comment
Please, Sign In to add comment