Advertisement
Gistrec

My SharedPtr

Apr 8th, 2018
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.93 KB | None | 0 0
  1. template <class Type>
  2. class SharedPtr {
  3. private:
  4.     Type* ptr_;
  5.     int* count;
  6.  
  7. public:
  8.     // Инициализируем счетчик ссылок в 1
  9.     // (конструктор создает первый SharedPtr, который хранит указатель)
  10.     explicit SharedPtr(Type *ptr = 0) {
  11.         if (ptr != 0) count = new int(1);
  12.         ptr_ = ptr;
  13.     }
  14.  
  15.     // В деструкторе мы уменьшаем значение счетчика на 1,
  16.     // если в объекте SharedPtr хранится ненулевой указатель
  17.     // (мы удаляем один SharedPtr, который указывает на объект в куче)
  18.     ~SharedPtr() {
  19.         if (ptr_ != 0) {
  20.             (*count)--;
  21.             if (*count == 0) {
  22.                 delete ptr_;
  23.                 delete count;
  24.             }
  25.         }
  26.     }
  27.     // В конструкторе копирования мы увеличиваем счетчик ссылок на 1,
  28.     // если копируемый SharedPtr содержит ненулевой указатель
  29.     // (конструктор копирования создает еще один SharedPtr с указателем на тот же самый объект)
  30.     SharedPtr(const SharedPtr &ptr) {
  31.         if (ptr.ptr_ != 0) {
  32.             (*(ptr.count))++;
  33.             count = ptr.count;
  34.         }
  35.         ptr_ = ptr.ptr_;
  36.     }
  37.  
  38.     // Оператор присваивания уменьшает счетчик ссылок левого операнда на 1,
  39.     // если внутри левого SharedPtr хранится ненулевой указатель,
  40.     // увеличивает счетчик правого SharedPtr на 1,
  41.     // если в правом SharedPtr хранится ненулевой указатель
  42.     // (обычное дело для оператора присваивания — сначала освобождаем старые ресурсы,
  43.     // потом выделяем новые,
  44.     // но при этом нужно быть особенно внимательным с присваиванием самому себе).
  45.     SharedPtr& operator=(const SharedPtr &ptr) {
  46.         if (this != &ptr) {
  47.             if (ptr_ != 0) {
  48.                 (*count)--;
  49.                 if (*(count) == 0) {
  50.                     delete ptr_;
  51.                     delete count;
  52.                 }
  53.             }
  54.             if (ptr.ptr_ != 0) {
  55.                 (*(ptr.count))++;
  56.                 count = ptr.count;
  57.             }
  58.             ptr_ = ptr.ptr_;
  59.         }
  60.         return *this;
  61.     }
  62.  
  63.     //  Освобождаем старый указатель, и захватываем новый
  64.     void reset(Type *ptr = 0) {
  65.         if (ptr_ != 0) {
  66.             (*count)--;
  67.             if (*(count) == 0) {
  68.                 delete ptr_;
  69.                 delete count;
  70.             }
  71.         }
  72.         ptr_ = ptr;
  73.         if (ptr_ != 0) count = new int(1);
  74.     }
  75.  
  76.     // Возвращает указатель, сохраненный внутри Shared
  77.     // (например, чтобы передать его в какую-то функцию)
  78.     Type* get() const {
  79.         return ptr_;
  80.     }
  81.  
  82.     Type& operator*() const {
  83.         return *ptr_;
  84.     }
  85.  
  86.     Type* operator->() const {
  87.         return ptr_;
  88.     }
  89. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement