c++ 共享指针简化版实现

[c++] 智能指针(shared_ptr, weak_ptr, unique_ptr)

(1) 共享指针是一个模板,通过模板参数指定共享指针关联的对象

(2) 共享指针中有一个计数,这个计数标志着有多少指针在共享当前这个对象。共享计数需要使用一个指针申请的空间来表示,这样方便在多个共享指针之间共享;如果直接使用一个变量,那么不便于在多个共享指针间共享。

① 构造时,引用计数初始化为 1

② 拷贝构造或者赋值的时候,引用计数增加 1

③ 析构的时候,引用计数减 1,这个时候判断引用计数是不是 0,如果是 0 的话,就将对象析构

#include <iostream>
#include <string>
#include <memory>

template <class T>
class MySharedPtr {
public:
  // 默认构造函数
  MySharedPtr(T *p = nullptr) {
    obj_ptr_ = p;
    obj_ref_count_ = new int(1);
  }

  // 拷贝构造函数
  MySharedPtr(const MySharedPtr<T>& obj) {
    obj_ptr_ = obj.obj_ptr_;
    obj_ref_count_ = obj.obj_ref_count_;
    (*obj_ref_count_)++;
  }

  // 赋值运算符
  MySharedPtr<T>& operator=(const MySharedPtr<T>& obj) {
    DecreaseRefCount();
    ++(*obj.obj_ref_count_);
    obj_ptr_ = obj.obj_ptr_;
    obj_ref_count_ = obj.obj_ref_count_;
    return *this;
  }

  // 返回对象的指针
  T* operator -> () {
    if (obj_ptr_ == nullptr) {
      throw std::runtime_error("nullptr");
    }
    std::cout << "operator ->\n" << std::endl;
    return obj_ptr_;
  }

  // 返回对象
  T& operator *() {
    if (obj_ptr_ == nullptr) {
      throw std::runtime_error("nullptr");
    }
    std::cout << "operator *\n";
    return *obj_ptr_;
  }

  int UseCount() {
    return *obj_ref_count_;
  }

  ~MySharedPtr() {
    DecreaseRefCount();
  }

  void DecreaseRefCount() {
    std::cout << "before ref count: " << *obj_ref_count_ << std::endl;
    (*obj_ref_count_)--;
    std::cout << "after ref count: " << *obj_ref_count_ << std::endl;
    if (*obj_ref_count_ == 0) {
      delete obj_ref_count_;
      delete obj_ptr_;
    }
  }

private:
  T *obj_ptr_ = nullptr;
  int *obj_ref_count_ = nullptr;
};

class Test {
public:
  Test(int num) {
    std::cout << "Test(), num = " << num << std::endl;
    num_ = num;
  }

  ~Test() {
    std::cout << "~Test(), num_ = " << num_ << std::endl;
  }

  void Do() {
    std::cout << "Do(), num = " << num_ <<std::endl;
  }

private:
  int num_;
};

int main() {
  MySharedPtr<Test> t1(new Test(1));
  // -> 运算符重载
  // t1->Do() 被解释为 (t1.operator ->)->Do()
  t1->Do();
  std::cout << "t1 use count: " << t1.UseCount() << std::endl;
  std::cout << "\n";

  // 没有初始化,抛异常
  MySharedPtr<Test> t2;
  try {
    t2->Do();
  } catch (std::exception& e) {
    std::cout << "exception: " << e.what() << std::endl;
  }
  std::cout << "\n";

  MySharedPtr<Test> t3(new Test(3));
  t3->Do();
  std::cout << "t3 use count: " << t3.UseCount() << std::endl;
  std::cout << "\n";

  // 赋值运算符
  t3 = t1;
  t3->Do();
  std::cout << "t1 use count: " << t1.UseCount() << ", t3 use count: " << t3.UseCount() << std::endl;
  std::cout << "\n";

  // 拷贝构造
  MySharedPtr<Test> t4 = t3;
  t4->Do();
  std::cout << "t1 use count: " << t1.UseCount() << ", t3 use count: " << t3.UseCount() << ", t4 use count: " << t4.UseCount() << std::endl;
  std::cout << "\n";
  return 0;
}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值