模拟 C++11 的shared_ptr

本文探讨了仿照C++11中shared_ptr原理的智能指针实现,并对其功能进行了详细解析,包括构造、赋值操作、析构及引用计数管理等关键点。

仿照C++11 中的shared_ptr 写的智能指针,不像源码那么好,自己还需要 努力

	template<class T>
	class RefCount
	{
	private:
		long refcount;
		T* Ptr;
	public:
		~RefCount()
		{
			cout<<"delete"<<endl;
		}
		virtual bool DeletePtr()
		{
			if(refcount==0)
			{
				delete Ptr;
				return true;
			}
			else
			{
				refcount--;
				return false;
			}
		}
		virtual void DeleteThis()
		{
			if(DeletePtr())
			{
				delete this;
			}
		}
		RefCount(T* _ptr):Ptr(_ptr),refcount(0){}
		inline bool Empty()
		{
			return refcount ==0;
		}

		inline void AddRef(){
			refcount++;
		}
		inline void DeRef()  
		{
			refcount --;
		}
	};
	template<class T>
	class JShare_Ptr
	{
	public:
		typedef JShare_Ptr<T > MyPtr;
		JShare_Ptr()
		{
			refcount = 0;
		}
		JShare_Ptr& operator=(const JShare_Ptr<T>& _Ptr)
		{
			if(this->ptr == _Ptr.ptr)
			{
				return *this;
			}else
			{
				delete refcount;
				this->ptr = _Ptr.ptr;
				this->refcount = _Ptr.refcount;
				refcount->AddRef();
			}
		}
		JShare_Ptr& operator=(JShare_Ptr<T>& _Ptr)
		{
			if(this->ptr == _Ptr.ptr)
			{
				return *this;
			}else
			{
				delete refcount;
				this->ptr = _Ptr.ptr;
				this->refcount = _Ptr.refcount;
				refcount->AddRef();
			}
		}
		JShare_Ptr(T* _ptr)
		{
			refcount = new RefCount<T>(_ptr);
			ptr = _ptr;

		}

		JShare_Ptr(const JShare_Ptr<T >& _Ptr)
		{
			Assign(_Ptr);
		}
		~JShare_Ptr()
		{
			(refcount)->DeleteThis();
		}
		T* operator ->(){return ptr;}
		T* operator*(){return ptr;}
	private:
		void Assign(const MyPtr& _Ptr)
		{
			ptr = _Ptr.ptr;
			refcount = _Ptr.refcount;
			(refcount) ->AddRef();
		}
	private:
		T* ptr;
		RefCount<T>* refcount;
	};
}


<think>好的,我现在需要帮助用户理解如何简单模拟实现shared_ptr。首先,我得回忆一下shared_ptr的基本概念和功能。shared_ptrC++中的智能指针,用于管理动态分配的内存,通过引用计数实现多个指针共享同一对象的所有权,当最后一个shared_ptr被销毁时,对象会被自动删除。 用户可能希望了解如何手动模拟这个机制,所以需要分解shared_ptr的关键组成部分。首先是引用计数,需要一个计数器来跟踪当前有多少个指针指向同一对象。其次是模板类,以支持不同类型的对象。此外,还需要考虑拷贝构造函数、赋值运算符、析构函数,以及如何管理引用计数的增加和减少。 接下来,我应该考虑如何实现这些部分。引用计数可以用一个动态分配的整数来实现,每个shared_ptr实例都持有该整数的指针。当拷贝构造或赋值时,引用计数递增;当析构或重置时,递减,并在计数为零时删除对象和计数器。 需要注意的是,线程安全问题,但用户可能只需要一个简单的实现,所以暂时可以忽略。此外,还要处理自赋值的情况,在赋值运算符中需要先检查是否是同一个对象,避免错误的释放。 然后,要设计模板类,比如命名为SharedPtr,包含指向对象的指针和指向引用计数的指针。构造函数需要接受原始指针,初始化引用计数为1。拷贝构造函数需要复制指针和引用计数,并递增计数。析构函数则递减计数,并在必要时释放资源。 可能还需要实现解引用操作符(*)和箭头操作符(->),以便用户像使用普通指针一样使用SharedPtr。另外,可以添加一个use_count()方法,让用户查看当前引用计数。 在编写示例代码时,要确保语法正确,比如在析构函数中正确使用delete和delete[],以及处理引用计数的更新。同时,要测试代码是否存在内存泄漏或悬空指针的问题。 用户可能对具体的实现步骤和代码结构感兴趣,所以需要分步骤解释,并提供代码示例。同时,要指出这个简单实现与标准库shared_ptr的区别,比如缺少自定义删除器、线程安全等,以帮助用户理解实际应用中的复杂性。 最后,确保回答结构清晰,逐步引导用户理解每个部分的作用,并强调注意事项和潜在的改进空间,这样用户就能掌握基本实现原理,并根据需要进一步扩展。</think>好的,我将分步骤为您解释如何简单模拟实现一个类似 `shared_ptr` 的智能指针,并附上代码示例和关键分析。 --- ### 实现原理 `shared_ptr` 的核心是 **引用计数** 机制: 1. 每个对象分配一个引用计数器 2. 拷贝时计数器+1 3. 析构时计数器-1 4. 当计数器归零时释放资源 --- ### 基础实现代码 ```cpp template <typename T> class SharedPtr { private: T* ptr; // 指向实际对象的指针 int* count; // 引用计数器(必须动态分配) public: // 构造函数 explicit SharedPtr(T* p = nullptr) : ptr(p), count(new int(1)) {} // 拷贝构造函数 SharedPtr(const SharedPtr& other) : ptr(other.ptr), count(other.count) { ++(*count); } // 赋值运算符 SharedPtr& operator=(const SharedPtr& other) { if (this != &other) { // 防止自赋值 // 减少原指针的引用 if (--(*count) == 0) { delete ptr; delete count; } // 复制新内容 ptr = other.ptr; count = other.count; ++(*count); } return *this; } // 析构函数 ~SharedPtr() { if (--(*count) == 0) { delete ptr; delete count; } } // 解引用操作符 T& operator*() const { return *ptr; } // 箭头操作符 T* operator->() const { return ptr; } // 获取引用计数 int use_count() const { return *count; } }; ``` --- ### 关键点解析 1. **引用计数器设计**: - 使用动态分配的 `int` 保证所有拷贝共享同一计数器 - 初始化时计数器设为1 2. **拷贝控制**: - 拷贝构造时复制指针并递增计数器 - 赋值运算符需处理自赋值,先减少原引用 3. **资源释放时机**: - 析构时递减计数器,当计数器归零时才释放资源 --- ### 使用示例 ```cpp class MyClass { public: MyClass() { std::cout << "Constructed\n"; } ~MyClass() { std::cout << "Destroyed\n"; } }; int main() { SharedPtr<MyClass> p1(new MyClass); // 计数器=1 { SharedPtr<MyClass> p2 = p1; // 计数器=2 std::cout << "Use count: " << p2.use_count() << "\n"; } // p2析构,计数器=1 SharedPtr<MyClass> p3; p3 = p1; // 计数器=2 } // p3,p1析构,计数器归零,对象销毁 ``` 输出结果: ``` Constructed Use count: 2 Destroyed ``` --- ### 与标准库差异 1. ❌ 缺少线程安全(标准库的引用计数是原子操作) 2. ❌ 不支持自定义删除器 3. ❌ 没有实现 `weak_ptr` 相关功能 4. ❌ 未处理循环引用问题 --- ### 改进方向 1. 使用原子操作保证线程安全 2. 添加模板参数支持自定义删除器 3. 实现 `make_shared` 优化内存布局 4. 添加 `weak_ptr` 支持 这个简化实现可以帮助理解智能指针的核心机制,实际开发中请直接使用标准库的 `std::shared_ptr`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值