C++11__共享型智能指针的一种靠谱的简单实现

C++11__共享型智能指针的一种靠谱的简易实现

  实现共享型智能指针的关键在于共享计数,这里利用资格资源管理类实现共享计数的相关操作。

一、实现代码
  以下代码提供了一种规范的共享型智能指针简单实现,注释应该比较清楚。

#pragma once
#include<utility>//std::swap

//资源管理类
class SharedCount
{
public:
	SharedCount() noexcept : _count(1) {}//资源取得时便是初始化时机
	void AddCount() {
		++_count;
	}
	//Redeuce需要有返回值,便于智能指针类析构函数使用
	long ReduceCount()noexcept {
		return --_count;
	}
	//获取计数
	long GetCount() const noexcept{
		return _count;
	}
private:
	long _count;
};

template<typename T>
class SmartPtr {
public:
	//模板的各个实例之间不具有friend关系,因而不能互访私有成员
	//需要显示声明友元
	template<typename U>
	friend class SmartPtr;

	//构造函数,不支持参数隐式转换
	explicit SmartPtr(T* ptr = nullptr):_ptr(ptr) 
	{
		if (_ptr) {
			_shared_count = new SharedCount();
			std::cout << "Defult Constructor! " << *_ptr << std::endl;
		}
		else std::cout << "Defult Constructor!(nullptr) "<< std::endl;

	}

	//拷贝构造,必须有非泛型版本,防止编译器自动生成缺省版本
	SmartPtr(const SmartPtr& oth)
	{
		_ptr = oth._ptr;
		if (_ptr) {
			oth._shared_count->AddCount();
			_shared_count = oth._shared_count;
			std::cout << "Copy Constructor! " << *_ptr << std::endl;
		}
		else std::cout << "Copy Constructor!(nullptr) " << std::endl;
		
	}

	//析构函数
	~SmartPtr() 
	{
		//如果_ptr不为空且计数为0,则delete
		if (_ptr && !_shared_count->ReduceCount())
		{
			std::cout << "Destructor! " << *_ptr << std::endl;
			delete _ptr;
			delete _shared_count;	
		}
		else std::cout << "Destructor!(nullptr) " << std::endl;
	}

	//移动构造
	template<typename U>
	SmartPtr(SmartPtr<U>&& oth)
	{
		_ptr = oth._ptr;
		if (_ptr) {
			_shared_count = oth._shared_count;
			oth._ptr = nullptr;
			std::cout << "Move Constructor! " << *_ptr << std::endl;
		}
		else std::cout << "Move Constructor!(nullptr) " << std::endl;

	}

	//泛型版本拷贝构造
	template<typename U>
	SmartPtr(const SmartPtr<U>& oth)
	{
		_ptr = oth._ptr;
		if (_ptr) {
			oth._shared_count->AddCount();
			_shared_count = oth._shared_count;
			std::cout << "Template Copy Constructor! " << *_ptr << std::endl;
		}
		else std::cout << "Template Copy Constructor!(nullptr) " << std::endl;
	}

	template<typename U>
	SmartPtr(const SmartPtr<U>& oth,T* ptr) noexcept
	{
		_ptr = oth._ptr;
		if (_ptr) {
			oth._shared_count->AddCount();
			_shared_count = oth._shared_count;
		}
	}
	//重载赋值,pass by value,传递副本(常用技巧)
	SmartPtr& operator=(SmartPtr rhs) noexcept
	{
		rhs.Swap(*this);//交换副本和*this
		return *this;
	}

	void Swap(SmartPtr& rhs) noexcept
	{
		using std::swap;
		swap(_ptr, rhs._ptr);
		swap(_shared_count, rhs._shared_count);
	}

	T* Get() const noexcept
	{
		if (_ptr) return _ptr;
		else return nullptr;
	}

	long UseCount() const noexcept
	{
		if (_ptr) {
			return _shared_count->GetCount();
		}
		else return 0;
	}

	T& operator*() const noexcept
	{
		return *_ptr;
	}

	T* operator->() const noexcept
	{
		return _ptr;
	}


private:
	T* _ptr;
	SharedCount* _shared_count;
};
//全局的智能指针对象Swap
template <typename T>
void Swap(SmartPtr<T>& lhs,SmartPtr<T>& rhs) noexcept
{
	lhs.Swap(rhs);
}

//简易版本二
template<typename T>
struct newFree {
	void operator()(T* ptr) {
		if (ptr != nullptr) {
			delete ptr;
			ptr = nullptr;
		}
	}
};

template<typename T>
struct mallocFree {
	void operator()(T* ptr) {
		if (ptr != nullptr) {
			free(ptr);
			ptr = nullptr;
		}
	}
};

template<typename T, typename DF = newFree<T>>
class Sptr {
private:
	T* ptr_;
	mutex mtx_;
	int* cnt_;

public:
	Sptr(T* ptr = nullptr):ptr_(ptr) {
		unique_lock<mutex> lock(mtx);
		if (ptr != nullptr) {
			cnt_ = new int(1);//RAII
		}
	}

	Sptr(const Sptr& sp) {
		ptr_ = sp.ptr_;
		cnt_ = sp.cnt_;
		unique_lock<mutex> lock(mtx);
		if (ptr_) {
			++(*cnt_);
		}
	}

	~Sptr() {
		unique_lock<mutex> lock(mtx);
		if (ptr_) {
			DF()(ptr_);
			delete cnt_;
			cnt_ = nullptr;
		}
	}

	//pass by value
	Sptr& operator=(Sptr sp) {
		sp.Swap(*this);
		return *this;
	}

	void Swap(Sptr& sp) {
		swap(ptr_, sp.ptr_);
		swap(cnt_, sp.cnt_);
	}

};

二、简单测试

#include <iostream>
#include"SmartPtr.h"
using namespace std;

int main()
{
    SmartPtr<char> pc;//默认构造
    SmartPtr<char> pc0 = SmartPtr<char>();//移动构造
    SmartPtr<char> pc1(new char('a'));//初值构造
    SmartPtr<char> pc2(pc1);//拷贝构造
    SmartPtr<char> pc3(new char('b'));
    SmartPtr<char> pc4;
    SmartPtr<char> pc5(new char('c'));
    
    pc5 = pc4;//pc5引用计数为0,析构掉。
    pc1 = pc3;//正常赋值
    pc1 = pc1;//自我赋值
    cout << "pc0.count = " << pc0.UseCount() << " pc0: nullptr" << endl;
    cout << "pc1.count = " << pc1.UseCount() << " pc1: " << *pc1.Get() << endl;
    cout << "pc2.count = " << pc2.UseCount() << " pc2: " << *pc2.Get() << endl;
    cout << "pc3.count = " << pc3.UseCount() << " pc3: " << *pc3.Get() << endl;

    return 0;
}

三、运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
unique_ptr 是 C++11 中引入的智能指针,用于管理动态分配的对象。 unique_ptr 的特性是:它是唯一拥有(unique ownership)被管理对象的智能指针,也就是说,同一时间只能有一个 unique_ptr 指向一个对象。当 unique_ptr 被销毁时,它会自动释放所管理的对象内存。 下面是 unique_ptr 的简单实现: ```cpp template <typename T> class unique_ptr { public: unique_ptr(T* ptr = nullptr) : m_ptr(ptr) {} ~unique_ptr() { delete m_ptr; } unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; unique_ptr(unique_ptr&& other) noexcept : m_ptr(other.m_ptr) { other.m_ptr = nullptr; } unique_ptr& operator=(unique_ptr&& other) noexcept { if (this != &other) { delete m_ptr; m_ptr = other.m_ptr; other.m_ptr = nullptr; } return *this; } T* get() const { return m_ptr; } T* operator->() const { return m_ptr; } T& operator*() const { return *m_ptr; } private: T* m_ptr; }; ``` 这是一个简化版本的 unique_ptr,它包含了基本的功能,如构造函数、析构函数、移动构造函数、移动赋值运算符,以及 get()、operator->() 和 operator*() 方法。 需要注意的是,这个实现并不完整,只是为了演示 unique_ptr 的基本原理和用法。实际使用时,应该考虑更多的细节,如空指针检查、自定义删除器等。另外,C++11 中已经提供了标准库中的 unique_ptr 实现,我们通常会使用标准库中的智能指针而不是自己实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值