手撕c++ shared_ptr(字节跳动手写算法)

#include <iostream>
#include <memory>
using namespace std;

namespace smart_pointer 
{

template <typename T>
struct defaultDeleter {
	void operator()(const T *ptr) {
		if(ptr) {
		  delete ptr;
		  ptr = nullptr;
		}
	}
};

template <typename T, typename Deleter=defaultDeleter<T> >
class shared_ptr {
public:
  shared_ptr();
  shared_ptr(T *ptr);
  shared_ptr(const shared_ptr &sp); //拷贝构造
  shared_ptr(shared_ptr &&sp);      //移动构造
  ~shared_ptr();

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

  shared_ptr &operator =(const shared_ptr &sp);  
  shared_ptr &operator =(shared_ptr &&sp); 

  T* get() const;
  void reset(T *ptr);
  void swap(shared_ptr &sp);
  int count();

private:
  atomic<int> *use_count;
  T *ptr;
};

template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr()
{}

template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(T *_ptr)
 : ptr(_ptr), use_count(new atomic<int>(1))
{}

template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(const shared_ptr &sp)
 : ptr(sp.ptr), use_count(sp.use_count)
{
  ++*use_count;
}

template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(shared_ptr &&sp)
{
  std::swap(ptr, sp.ptr);
  std::swap(use_count, sp.use_count);
}

template <typename T, typename Deleter>
shared_ptr<T, Deleter>::~shared_ptr()
{
  if(ptr) {
  	--*use_count;
  	if(*use_count <= 0) {
  	  Deleter()(ptr);
  	  delete use_count;
  	  cout << "shared_ptr dctor" << endl;
  	}
  }
}

template <typename T, typename Deleter>
T *shared_ptr<T, Deleter>::operator-> () const
{
  return ptr;
}

template <typename T, typename Deleter>
T& shared_ptr<T, Deleter>::operator* () const 
{
  return *ptr;
} 

template <typename T, typename Deleter>
shared_ptr<T, Deleter>::operator bool() const
{
  return ptr!=nullptr;
}

/* 异常安全赋值 */
template <typename T, typename Deleter>
shared_ptr<T, Deleter> &shared_ptr<T, Deleter>::operator= (const shared_ptr<T, Deleter> &sp)
{
#if 1
  //copy and swap
  shared_ptr<T, Deleter> tmp(sp);
  swap(tmp);
  return *this;
#else
  //自我赋值
  if(sp.ptr == ptr) return *this;

  ptr = sp.ptr;
  use_count = sp.use_count;
  ++*use_count;
  return *this;
#endif
}

template <typename T, typename Deleter>
shared_ptr<T, Deleter> &shared_ptr<T, Deleter>::operator= (shared_ptr<T, Deleter> &&sp)
{
  std::swap(ptr, sp.ptr);
  std::swap(use_count, sp.use_count);
  return *this;
}

template <typename T, typename Deleter>
T* shared_ptr<T, Deleter>::get() const
{
  return ptr;
}

template <typename T, typename Deleter>
void shared_ptr<T, Deleter>::reset(T *_ptr)
{
  shared_ptr<T, Deleter>().swap(*this);

  ptr = _ptr;
  use_count = new atomic<int>(1);
}

template <typename T, typename Deleter>
void shared_ptr<T, Deleter>::swap(shared_ptr<T, Deleter> &sp)
{
  std::swap(ptr, sp.ptr);
  std::swap(use_count, sp.use_count); 
}

template <typename T, typename Deleter>
int shared_ptr<T, Deleter>::count()
{
  return *use_count;
}

}; //namespace smart_pointer


int main(int argc, char *argv[])
{
  {
    smart_pointer::shared_ptr<int> p(new int(12));
    smart_pointer::shared_ptr<int> p1(p);
    *p1 = 2;
    cout << *p << endl;
    cout << p.count() << endl;

    //异常安全测试
    p = p;
    cout << *p << endl;
    cout << p.count() << endl;
  }

  {
  	smart_pointer::shared_ptr<int> p(new int(12));
  	p.reset(new int(13));
  	cout << *p << endl;

  	//右值赋值测试
  	p = smart_pointer::shared_ptr<int>(new int(14));
  	cout << *p << endl;

  	//移动构造测试
  	smart_pointer::shared_ptr<int> p1(smart_pointer::shared_ptr<int>(new int(15)));
  	cout << *p1 << endl;
  }
  
  return 0;
}

有关更多 C++ 技术分享,请关注 「码尘」
在这里插入图片描述

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
C++ 中的 `shared_ptr` 是一个智能指针,用于管理动态分配的对象。它是 C++11 引入的一个特性,位于 `<memory>` 头文件中。 `shared_ptr` 可以用来共享一个对象的所有权。它会记录有多少个 `shared_ptr` 共享同一个对象,并且当所有的 `shared_ptr` 都不再使用该对象时,会自动释放对象的内存。 使用 `shared_ptr` 的语法如下所示: ```cpp #include <memory> int main() { // 创建 shared_ptr std::shared_ptr<int> ptr1 = std::make_shared<int>(42); // 共享对象的所有权 std::shared_ptr<int> ptr2 = ptr1; // 使用 shared_ptr 操作对象 *ptr1 = 100; std::cout << *ptr2 << std::endl; // 输出:100 // 释放对象内存 ptr1.reset(); std::cout << *ptr2 << std::endl; // 输出:100 return 0; } ``` 在上述示例中,我们首先创建了一个 `shared_ptr`,并使用 `make_shared` 函数动态分配一个整数对象,并将其初始化为 42。然后我们创建了另一个 `shared_ptr`,并将其指向第一个 `shared_ptr` 所管理的对象。通过这种方式,两个 `shared_ptr` 共享同一个整数对象。我们可以通过任意一个 `shared_ptr` 来访问和操作该对象,并且当两个 `shared_ptr` 都不再使用该对象时,会自动释放对象的内存。 需要注意的是,`shared_ptr` 使用引用计数的方式来管理对象的生命周期。当引用计数变为零时,即没有任何 `shared_ptr` 指向该对象时,会自动调用对象的析构函数来销毁对象。这种智能指针可以避免常见的内存泄漏问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值