Seredenko-V

ArrayPtr

Aug 1st, 2022
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.67 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <cstdlib>
  4. #include <cassert>
  5. #include <utility>
  6. #include <algorithm>
  7.  
  8. template <typename Type>
  9. class ArrayPtr {
  10. public:
  11.     // Инициализирует ArrayPtr нулевым указателем
  12.     ArrayPtr() = default;
  13.  
  14.     // Создаёт в куче массив из size элементов типа Type.
  15.     // Если size == 0, поле raw_ptr_ должно быть равно nullptr
  16.     explicit ArrayPtr(size_t size) {
  17.         if (size != 0) {
  18.             Type* arr = new Type[size];
  19.             raw_ptr_ = arr;
  20.         }
  21.     }
  22.  
  23.     // Конструктор из сырого указателя, хранящего адрес массива в куче либо nullptr
  24.     explicit ArrayPtr(Type* raw_ptr) noexcept
  25.         : raw_ptr_(raw_ptr) {
  26.     }
  27.  
  28.     // Запрещаем копирование
  29.     ArrayPtr(const ArrayPtr&) = delete;
  30.  
  31.     ~ArrayPtr() {
  32.         delete[] raw_ptr_;
  33.         raw_ptr_ = nullptr;
  34.     }
  35.  
  36.     // Запрещаем присваивание
  37.     ArrayPtr& operator=(const ArrayPtr&) = delete;
  38.  
  39.     // Конструктор перемещения
  40.     ArrayPtr(ArrayPtr&& rvalue) noexcept {
  41.         raw_ptr_ = std::move(rvalue.raw_ptr_);
  42.         /* когда rvalue выходит за пределы области видимости, вызывается деструктор rvalue, и rvalue.raw_ptr_
  43.         удаляется. Если в этот момент rvalue.raw_ptr_ всё еще указывает на тот же объект, что и raw_ptr_, тогда
  44.         raw_ptr_ останется висячим указателем. Когда объект, содержащий raw_ptr_, в конечном итоге будет
  45.         использован(или уничтожен), мы получим неопределенное поведение. */
  46.         rvalue.raw_ptr_ = nullptr;
  47.     }
  48.  
  49.     // Перемещающий оператор присваивания
  50.     ArrayPtr& operator=(ArrayPtr&& rvalue) noexcept {
  51.         if (this->raw_ptr_ == rvalue.raw_ptr_) {
  52.             return *this;
  53.         }
  54.         this->swap(rvalue);
  55.         return *this;
  56.     }
  57.  
  58.     // Прекращает владением массивом в памяти, возвращает значение адреса массива
  59.     // После вызова метода указатель на массив должен обнулиться
  60.     [[nodiscard]] Type* Release() noexcept {
  61.         Type* ptr_arr = raw_ptr_;
  62.         raw_ptr_ = nullptr;
  63.         return ptr_arr;
  64.     }
  65.  
  66.     // Возвращает ссылку на элемент массива с индексом index
  67.     Type& operator[](size_t index) noexcept {
  68.         return *(raw_ptr_ + index);
  69.     }
  70.  
  71.     // Возвращает константную ссылку на элемент массива с индексом index
  72.     const Type& operator[](size_t index) const noexcept {
  73.         return *(raw_ptr_ + index);
  74.     }
  75.  
  76.     // Возвращает true, если указатель ненулевой, и false в противном случае
  77.     explicit operator bool() const {
  78.         return this->raw_ptr_ == nullptr ? false : true;
  79.     }
  80.  
  81.     // Возвращает значение сырого указателя, хранящего адрес начала массива
  82.     Type* Get() const noexcept {
  83.         return raw_ptr_;
  84.     }
  85.  
  86.     // Обменивается значениям указателя на массив с объектом other
  87.     void swap(ArrayPtr& other) noexcept {
  88.         std::swap(this->raw_ptr_, other.raw_ptr_);
  89.     }
  90.  
  91. private:
  92.     Type* raw_ptr_ = nullptr;
  93. };
Advertisement
Add Comment
Please, Sign In to add comment