智能指针及share_ptr的实现
智能指针是通过类的构造函数和析构函数来实现对一个指针的管理,避免程序员申请的空间忘记释放,造成内存泄漏情况的发生。主要有auto_ptr/unique_ptr/shared_ptr/weak_ptr;
unique_ptr是独占式拥有或严格拥有的,保证同一时间只有一个智能指针可以指向该对象,对于避免资源泄漏非常有用。
shared_ptr是强引用,共享式的,可以多个智能指针指向同一对象。该对象和其相关资源会在最后一个引用销毁的时候释放。它主要是使用计数机制来表明资源被几个指针共享。可以通过use_count查看资源的所有者个数。除了可以通过new构造,还可以传入auto_ptr/unique_ptr/weak_ptr来构造。
shared_ptr是解决auto_ptr在对象所有权上的局限性(auto_ptr是独占的)。
weak_ptr是弱引用,指向一个shared_ptr管理的对象,不会增加该对象的引用计数。进行该对象的内存管理的还是那个强引用的shared_ptr。也就是说,weak_ptr不控制对象的声明周期,只是提供了对象的一个访问手段。这是为了解决shared_ptr引用死锁的问题。如果两个都是shared_ptr,并且同时指向对方,那么即使他们同时释放了,两个的引用计数也还都是1。因此,可以采用一个为shared_ptr A,一个为weak_ptr B的方案,B指向A的时候,A的引用计数不会增加。
#include <iostream> #include <assert.h> using namespace std; /* 允许多个指针指向同一个变量对象。 智能指针的重要变量如下。 引用对象的指针、引用对象的引用次数(类型都是指针) 对引用计数值,是根据新指向的对象是不是智能指针进行赋值1和加1操作。 */ template<typename T> class my_share_ptr { private: T* mptr; size_t* mcount; public: //初始化 my_share_ptr(T* _ptr = nullptr) :mptr(_ptr) { if (mptr != nullptr) { mcount = new size_t(1); } else { mcount = new size_t(0); } } //拷贝构造 my_share_ptr(const my_share_ptr& ptr) { if (this == &ptr) return;//自我不可拷贝 this->mptr = ptr.mptr; this->mcount = ptr.mcount; (*this->mcount++); } //赋值运算符 my_share_ptr& operator=(const my_share_ptr& ptr) { if (this->mptr == ptr.mptr) return *this; if (this->mptr) { (*this->mcount--); if (*this->mcount == 0) { delete this->mptr; delete this->mcount; } } this->mptr = ptr.mptr; this->mcount = ptr.mcount; (*this->mcount)++; return *this; } //重载* T& operator*() { assert(this->mptr == nullptr); return *(this->mptr); } //重载-> T* operator->() { assert(this->mptr == nullptr); return this->mptr; } //析构函数 ~my_share_ptr() { if (*this->mcount == 0) { delete this->mptr; delete this->mcount; cout << "释放" << endl; } else { (*(this->mcount))--; } if (*(this->mcount) == 0) { delete this->mptr; delete this->mcount; cout << "释放" << endl; } } size_t use_count() { return *(this->mcount); } }; int main() { my_share_ptr<int> s1(new int(2)); my_share_ptr<int> s2(s1);//s2指向s1 my_share_ptr<int> s3(new int(3)); s2 = s3;//s2指向s3 cout << s1.use_count() << endl;//1 cout << s2.use_count() << endl;//2。s2有值了之后,s2和s3相互指向 cout << s3.use_count() << endl;//2 return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!