智能指针实现

智能指针简单实现

智能指针可以简化资源的管理,从根本上消除资源(包括内存)泄漏的可能性。智能指针本质上并不神秘,其实就是 RAII 资源管理功能的自然展现而已。

unique_ptr 算是一种较为安全的智能指针了。但是,一个对象只能被单个 unique_ptr所拥有,这显然不能满足所有使用场合的需求。

多个不同的 shared_ptr 不仅可以共享一个对象,在共享同一对象时也需要同时共享同一个计数。当最后一个指向对象(和共享计数)的 shared_ptr 析构时,它需要删除对象和共享计数。我们下面就来实现一下。

// shared_ptr
#include <utility> // std::swap

class shared_count {
public:
	shared_count() noexcept
		: count_(1) {}
	void add_count() noexcept
	{
		++count_;
	}
	long reduce_count() noexcept
	{
		return --count_;
	}
	long get_count() const noexcept
	{
		return count_;
	}
private:
	long count_;
};

template <typename T>
class smart_ptr {
public:
// 模板的各个实例间并不天然就有 friend 关系,因而不能互访私有成员 ptr_ 和shared_count_
	template <typename U>
	friend class smart_ptr;
	
	explicit smart_ptr(T* ptr = nullptr)
		: ptr_(ptr)
	{
		if (ptr) {
			shared_count_ =
				new shared_count();
		}
	}
	~smart_ptr()
	{
		printf("~smart_ptr(): %p\n", this);
		if (ptr_ &&
			!shared_count_
			->reduce_count()) {
			delete ptr_;
			delete shared_count_;
		}
	}
	template <typename U>
	smart_ptr(const smart_ptr<U>& other) noexcept
	{
		ptr_ = other.ptr_;
		if (ptr_) {
			other.shared_count_->add_count();
			shared_count_ = other.shared_count_;
		}
	}
	template <typename U>
	smart_ptr(smart_ptr<U>&& other) noexcept
	{
		ptr_ = other.ptr_;
		if (ptr_) {
			shared_count_ =
				other.shared_count_;
			other.ptr_ = nullptr;
		}
	}
	template <typename U>
	smart_ptr(const smart_ptr<U>& other,
		T* ptr) noexcept
	{
		ptr_ = ptr;
		if (ptr_) {
			other.shared_count_
				->add_count();
			shared_count_ =
				other.shared_count_;
		}
	}
	smart_ptr&
		operator=(smart_ptr rhs) noexcept
	{
		rhs.swap(*this);
		return *this;
	}
	T* get() const noexcept
	{
		return ptr_;
	}
	long use_count() const noexcept
	{
		if (ptr_) {
			return shared_count_
				->get_count();
		}
		else {
			return 0;
		}
	}
	void swap(smart_ptr& rhs) noexcept
	{
		using std::swap;
		swap(ptr_, rhs.ptr_);
		swap(shared_count_,
			rhs.shared_count_);
	}
	T& operator*() const noexcept
	{
		return *ptr_;
	}
	T* operator->() const noexcept
	{
		return ptr_;
	}
	operator bool() const noexcept
	{
		return ptr_;
	}
private:
	T* ptr_;
	shared_count* shared_count_;
};
template <typename T>
void swap(smart_ptr<T>& lhs,
	smart_ptr<T>& rhs) noexcept
{
	lhs.swap(rhs);
}
template <typename T, typename U>
smart_ptr<T> static_pointer_cast(
	const smart_ptr<U>& other) noexcept
{
	T* ptr = static_cast<T*>(other.get());
	return smart_ptr<T>(other, ptr);
}
template <typename T, typename U>
smart_ptr<T> reinterpret_pointer_cast(
	const smart_ptr<U>& other) noexcept
{
	T* ptr = reinterpret_cast<T*>(other.get());
	return smart_ptr<T>(other, ptr);
}
template <typename T, typename U>
smart_ptr<T> const_pointer_cast(
	const smart_ptr<U>& other) noexcept
{
	T* ptr = const_cast<T*>(other.get());
	return smart_ptr<T>(other, ptr);
}
template <typename T, typename U>
smart_ptr<T> dynamic_pointer_cast(
	const smart_ptr<U>& other) noexcept
{
	T* ptr = dynamic_cast<T*>(other.get());
	return smart_ptr<T>(other, ptr);
}

参考链接

Stack Overflow, GManNickG’s answer to “What is the copy-and-swap
idiom?”.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值