Gistrec icon

My SharedPtr

Gistrec | PRO | 04/08/18 01:53:10 PM UTC | 0 ⭐ | 570 👁️ | Never ⏰ | []
C++ |

2.93 KB

|

None

|

0 👍

/

0 👎

template <class Type>
class SharedPtr {
private:
    Type* ptr_;
    int* count;
 
public:
    // Инициализируем счетчик ссылок в 1
    // (конструктор создает первый SharedPtr, который хранит указатель)
    explicit SharedPtr(Type *ptr = 0) {
        if (ptr != 0) count = new int(1);
        ptr_ = ptr;
    }
 
    // В деструкторе мы уменьшаем значение счетчика на 1,
    // если в объекте SharedPtr хранится ненулевой указатель
    // (мы удаляем один SharedPtr, который указывает на объект в куче)
    ~SharedPtr() {
        if (ptr_ != 0) {
            (*count)--;
            if (*count == 0) {
                delete ptr_;
                delete count;
            }
        }
    }
    // В конструкторе копирования мы увеличиваем счетчик ссылок на 1,
    // если копируемый SharedPtr содержит ненулевой указатель
    // (конструктор копирования создает еще один SharedPtr с указателем на тот же самый объект)
    SharedPtr(const SharedPtr &ptr) {
        if (ptr.ptr_ != 0) {
            (*(ptr.count))++;
            count = ptr.count;
        }
        ptr_ = ptr.ptr_;
    }
 
    // Оператор присваивания уменьшает счетчик ссылок левого операнда на 1,
    // если внутри левого SharedPtr хранится ненулевой указатель,
    // увеличивает счетчик правого SharedPtr на 1,
    // если в правом SharedPtr хранится ненулевой указатель
    // (обычное дело для оператора присваивания — сначала освобождаем старые ресурсы,
    // потом выделяем новые,
    // но при этом нужно быть особенно внимательным с присваиванием самому себе).
    SharedPtr& operator=(const SharedPtr &ptr) {
        if (this != &ptr) {
            if (ptr_ != 0) {
                (*count)--;
                if (*(count) == 0) {
                    delete ptr_;
                    delete count;
                }
            }
            if (ptr.ptr_ != 0) {
                (*(ptr.count))++;
                count = ptr.count;
            }
            ptr_ = ptr.ptr_;
        }
        return *this;
    }
 
    //  Освобождаем старый указатель, и захватываем новый
    void reset(Type *ptr = 0) {
        if (ptr_ != 0) {
            (*count)--;
            if (*(count) == 0) {
                delete ptr_;
                delete count;
            }
        }
        ptr_ = ptr;
        if (ptr_ != 0) count = new int(1);
    }
 
    // Возвращает указатель, сохраненный внутри Shared
    // (например, чтобы передать его в какую-то функцию)
    Type* get() const {
        return ptr_;
    }
 
    Type& operator*() const {
        return *ptr_;
    }
 
    Type* operator->() const {
        return ptr_;
    }
};

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎