智能指针及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;

}
复制代码

 

posted @   花与不易  阅读(314)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示