Advertisement
AlexDanilin

C7. Урок 8-1. Копирование объектов часть 2

Aug 17th, 2023
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.09 KB | None | 0 0
  1. #include <cassert>
  2.  
  3. // Умный указатель, удаляющий связанный объект при своём разрушении.
  4. // Параметр шаблона T задаёт тип объекта, на который ссылается указатель
  5. template <typename T>
  6. class ScopedPtr {
  7. public:
  8.     // Конструктор по умолчанию создаёт нулевой указатель,
  9.     // так как поле ptr_ имеет значение по умолчанию nullptr
  10.     ScopedPtr() = default;
  11.  
  12.     // Создаёт указатель, ссылающийся на переданный raw_ptr.
  13.     // raw_ptr ссылается либо на объект, созданный в куче при помощи new,
  14.     // либо является нулевым указателем
  15.     // Спецификатор noexcept обозначает, что метод не бросает исключений
  16.     explicit ScopedPtr(T* raw_ptr) noexcept {
  17.         // Реализуйте самостоятельно
  18.         ptr_ = raw_ptr;
  19.     }
  20.  
  21.     // Удаляем у класса конструктор копирования
  22.     ScopedPtr(const ScopedPtr&) = delete;
  23.  
  24.     // Деструктор. Удаляет объект, на который ссылается умный указатель.
  25.     ~ScopedPtr() {
  26.         // Реализуйте тело деструктора самостоятельно
  27.         delete ptr_;
  28.     }
  29.  
  30.     // Возвращает указатель, хранящийся внутри ScopedPtr
  31.     T* GetRawPtr() const noexcept {
  32.         // Напишите код метода самостоятельно
  33.         return ptr_;
  34.     }
  35.  
  36.     // Прекращает владение объектом, на который ссылается умный указатель.
  37.     // Возвращает прежнее значение "сырого" указателя и устанавливает поле ptr_ в null
  38.     T* Release() noexcept {
  39.         // Реализуйте самостоятельно
  40.         T*ptr_helper = ptr_;
  41.         ptr_ = nullptr;
  42.         return ptr_helper;
  43.     }
  44.  
  45. private:
  46.     T* ptr_ = nullptr;
  47.     T* ptr_helper = nullptr;
  48. };
  49.  
  50. // Этот main тестирует класс ScopedPtr
  51. int main() {
  52.     // Вспомогательный "шпион", позволяющий узнать о своём удалении
  53.     struct DeletionSpy {
  54.         explicit DeletionSpy(bool& is_deleted)
  55.             : is_deleted_(is_deleted) {
  56.         }
  57.         ~DeletionSpy() {
  58.             is_deleted_ = true;
  59.         }
  60.         bool& is_deleted_;
  61.     };
  62.  
  63.     // Проверяем автоматическое удаление
  64.     {
  65.         bool is_deleted = false;
  66.         {
  67.             // настраиваем "шпион", чтобы при своём удалении он выставил is_deleted в true
  68.             DeletionSpy* raw_ptr = new DeletionSpy(is_deleted);
  69.             ScopedPtr<DeletionSpy> p(raw_ptr);
  70.             assert(p.GetRawPtr() == raw_ptr);
  71.             assert(!is_deleted);
  72.             // При выходе из блока деструктор p должен удалить "шпиона"
  73.         }
  74.         // Если деструктор умного указателя работает правильно, шпион перед своей "смертью"
  75.         // должен выставить is_deleted в true
  76.         assert(is_deleted);
  77.     }
  78.  
  79.     // Проверяем работу метода Release
  80.     {
  81.         bool is_deleted = false;
  82.         DeletionSpy* raw_ptr = new DeletionSpy(is_deleted);
  83.         {
  84.             ScopedPtr<DeletionSpy> scoped_ptr(raw_ptr);
  85.             assert(scoped_ptr.Release() == raw_ptr);
  86.             assert(scoped_ptr.GetRawPtr() == nullptr);
  87.             // После Release умный указатель не ссылается на объект и не удаляет его при своём удалении
  88.         }
  89.         assert(!is_deleted);
  90.         delete raw_ptr;
  91.         assert(is_deleted);
  92.     }
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement