【C++实现智能指针】

7 篇文章 0 订阅


一、C++实现shared_ptr

实现要点

  1. 模板类,对实际指针数据类型T*进行封装,有效防止内存泄露,类实例在离开作用域后自动析构
  2. 共享引用次数(指针类型),在构造函数中需要new一块内存,在清零的情况下delete
  3. 重载拷贝构造函数、赋值函数,count加1
  4. 重载解引用operator*和取成员符号operator->
  5. 重载析构函数,引用次数减1,并判断是否delete
#include <iostream>
#include <memory>

template <typename T>
class shared_ptr {
private:
  int *count_;
  T *ptr_;
public:
  shared_ptr(T *p) : count_(new int (1)), ptr_(p) {} // 构造函数
  shared_ptr(shared_ptr<T>& other) : count_(&(++*other.count_)), ptr_(other.ptr_) {} // 拷贝构造函数
  T* operator->() { return ptr_; } // 重载->
  T& operator*() { return *ptr_; }  // 重载*
  shared_ptr<T>& operator=(shared_ptr<T>& other) {  // 赋值函数
    ++*other.count_;
    if (this->ptr_ && 0 == --*this->count_) {
      delete count_;
      delete ptr_;
    }
    this->ptr_ = other.ptr_;
    this->count_ = other.count_;
    return *this;
  }
  ~shared_ptr() {   // 析构函数
    if (--*count_ == 0) {
      delete count_;
      delete ptr_;
    }
  }
  int use_count() { return *count_; }
};

int main() {
  std::cout << "hello lch!" << std::endl;

  shared_ptr<int> temp1(new int(100));
  shared_ptr<int> temp2(temp1);  
  std::cout << temp1.use_count() << std::endl;
  std::cout << temp2.use_count() << std::endl;
  std::cout << *temp1 << std::endl;
  std::cout << *temp2 << std::endl;

  std::shared_ptr<int> temp3(new int (200));
  std::cout << temp3.use_count() << std::endl;
  std::cout << *temp3 << std::endl;

  std::cout << "end lch!" << std::endl;
  return 0;
}

二、C++实现unique_ptr

实现要点

  1. 模板类,对实际指针数据类型T*进行封装,有效防止内存泄露,类实例在离开作用域后自动析构
  2. 禁用拷贝构造和赋值函数,独占指针所有权
  3. 实现移动构造函数和移动赋值函数(右值只用),支持所有权转移(std::move)
  4. reset和release实现
  5. 重载解引用operator*和取成员符号operator->
#include <iostream>
#include <memory>
#include <iostream>

template <typename T>
class unique_ptr {
 public:
  constexpr unique_ptr() noexcept : ptr_(nullptr) {}
  constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() {}  // typedef decltype(nullptr) nullptr_t;
  explicit unique_ptr(T *ptr) noexcept : ptr_(ptr) {}
  ~unique_ptr() noexcept { delete ptr_; }
  unique_ptr(const unique_ptr &) = delete;  // 禁用拷贝构造函数
  unique_ptr& operator=(const unique_ptr &) = delete;  // 禁用赋值函数
  unique_ptr(unique_ptr &&other) noexcept : ptr_(other.release()) {}
  unique_ptr &operator=(unique_ptr &&other) noexcept {
    this->reset(other.release());
    return *this;
  }
  unique_ptr &operator=(nullptr_t) {
    this->reset();
    return *this;
  }
  T& operator*() const noexcept { return *ptr_; }
  T* operator->() const noexcept { return ptr_; }
  T* release() noexcept {  // return std::exchange(ptr_, nullptr); // C++14用法
    T* temp = ptr_;
    ptr_ = nullptr;
    return temp;
  }
  void reset(T *ptr) noexcept {  // return std::exchange(ptr_, ptr); // C++14用法
    ptr_ = ptr;
  }
  T* get() const noexcept { return ptr_; }
  void swap(unique_ptr &other) noexcept { std::swap(ptr_, other.ptr_); };
  operator bool() const noexcept { return static_cast<bool>(ptr_); }
  void test_print() { std::cout << "test number is " << ++num << std::endl; }
 private:
  T *ptr_;
  static int num;
};

template <typename T>
int unique_ptr<T>::num = 0;

template <typename T, typename... Args>
auto make_unique(Args &&... args) {
  return unique_ptr<T>(new T(std::forward(args)...));
}

int main() {
  std::cout << "hello lch !!!" << std::endl;
  unique_ptr<int> ptr(new int (100));
  std::cout << &ptr << std::endl;
  std::cout << *ptr << std::endl;
  std::cout << bool(ptr) << std::endl;
  (void)ptr.test_print();

  unique_ptr<int> ptr1;
  std::cout << bool(ptr1) << std::endl;
  ptr1 = make_unique<int>();
  *ptr1 = 200;
  std::cout << &ptr1 << std::endl;
  std::cout << *ptr1 << std::endl;
  std::cout << bool(ptr1) << std::endl;
  (void)ptr1.test_print();

  unique_ptr<int> *ptr2 = new unique_ptr<int>();
  std::cout << &ptr2 << std::endl;
  std::cout << *ptr2 << std::endl;
  (void)ptr2->test_print();
  std::cout << "end lch !!!" << std::endl;
  return 0;
}



总结

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自动驾驶小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值