SmartPointer

// smart_pointer.h
#ifndef SMART_POINTER_H
#define SMART_POINTER_H

template <typename T>
class SmartPointer {
 public:
  explicit SmartPointer(T* ptr = nullptr);
  ~SmartPointer();
  SmartPointer(const SmartPointer& other);
  SmartPointer& operator=(const SmartPointer& other);
  SmartPointer(SmartPointer&& other) noexcept;
  SmartPointer& operator=(SmartPointer&& other) noexcept;

  T& operator*() const;
  T* operator->() const;
  T* get() const;

 private:
  void UnRef();
  void Ref(const SmartPointer& other);

  T* ptr_;
  unsigned* ref_count_;
};

template <typename T>
SmartPointer<T>::SmartPointer(T* ptr) : ptr_(ptr) {
  if (ptr_) {
    ref_count_ = new unsigned(1);
  } else {
    ref_count_ = nullptr;
  }
}

template <typename T>
SmartPointer<T>::~SmartPointer() {
  UnRef();
}

template <typename T>
SmartPointer<T>::SmartPointer(const SmartPointer& other) {
  Ref(other);
}

template <typename T>
SmartPointer<T>& SmartPointer<T>::operator=(const SmartPointer& other) {
  if (this != &other) {
    UnRef();
    Ref(other);
  }
  return *this;
}

template <typename T>
SmartPointer<T>::SmartPointer(SmartPointer&& other) noexcept
    : ptr_(other.ptr_), ref_count_(other.ref_count_) {
  other.ptr_ = nullptr;
  other.ref_count_ = nullptr;
}

template <typename T>
SmartPointer<T>& SmartPointer<T>::operator=(SmartPointer&& other) noexcept {
  if (this != &other) {
    UnRef();
    ptr_ = other.ptr_;
    ref_count_ = other.ref_count_;
    other.ptr_ = nullptr;
    other.ref_count_ = nullptr;
  }
  return *this;
}

template <typename T>
T& SmartPointer<T>::operator*() const {
  return *ptr_;
}

template <typename T>
T* SmartPointer<T>::operator->() const {
  return ptr_;
}

template <typename T>
T* SmartPointer<T>::get() const {
  return ptr_;
}

template <typename T>
void SmartPointer<T>::UnRef() {
  if (ref_count_) {
    --(*ref_count_);
    if (*ref_count_ == 0) {
      delete ptr_;
      delete ref_count_;
      ptr_ = nullptr;
      ref_count_ = nullptr;
    }
  }
}

template <typename T>
void SmartPointer<T>::Ref(const SmartPointer& other) {
  ptr_ = other.ptr_;
  ref_count_ = other.ref_count_;
  if (ref_count_) {
    ++(*ref_count_);
  }
}

#endif  // SMART_POINTER_H

results matching ""

    No results matching ""