智能指针概述

简单智能指针的实现

#include<iostream>
using namespace std;
// 智能指针 保证能做到资源的自动释放!!!
// 利用栈上的对象出作用域自动释放
template<typename T>
class CSmartPtr
{
public:
    CSmartPtr(T *ptr=nullptr)
    {
        mptr=ptr;
    }
    ~CSmartPtr()
    {
        delete mptr;
    }
    T& operator*()
    {
        return *mptr;
    }
    T *operator->(){ return mptr;}
private:
    T *mptr;
};
int main()
{
    // int *p=new int;
    CSmartPtr<int> ptr1(new int);
    *ptr1=20;
    class Test
    {
    public:
        void test() {cout<<"call Test::test"<<endl;}
    };
    CSmartPtr<Test> ptr2(new Test());
    ptr2->test();
    cout<<"123"<<endl;
    return 0;
}

不带引用计数的智能指针

auto_ptr

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现带引用计数的智能指针

#include<iostream>
#include<memory>
using namespace std;
// 对资源进行引用计数的类
template<typename T>
class RefCnt
{
public:
    RefCnt(T *ptr=nullptr)
    {
        mptr=ptr;
        if(mptr!=nullptr)
        {
            mcount=1;
        }
        else{
            mcount=0;
        }
    }
    void addRef()
    {
        // 添加资源的引用计数
        mcount++;
    }
    int delRef()
    {
        // 添加资源的引用计数
         return --mcount;
    }
private:
    T *mptr;
    int mcount;
};
// 智能指针 保证能做到资源的自动释放!!!
// 利用栈上的对象出作用域自动释放
template<typename T>
class CSmartPtr
{
public:
    CSmartPtr(T *ptr=nullptr)
    {
        mptr=ptr;
        mpRefCnt=new RefCnt<T>(mptr);
    }
    CSmartPtr(const CSmartPtr<T>&src)
    {
        mptr=new T(*src.mptr);
        mpRefCnt=src.mpRefCnt;
        if(mptr!=nullptr)
        {
            mpRefCnt->addRef();
        }
    }
    CSmartPtr<T> &operator=(const CSmartPtr<T>&src)
    {
        if(this==&src)
        {
            return *this;
        }
        if(0==mpRefCnt->delRef())
        {
            delete mptr;
        }
        mptr=src.mptr;
        mpRefCnt=src.mpRefCnt;
        mpRefCnt->addRef();
        return *this;
    }
    ~CSmartPtr()
    {
        if(0==mpRefCnt->delRef())
        {
            mptr=nullptr;
            delete mptr;
        }
    }
    T& operator*()
    {
        return *mptr;
    }
    T *operator->(){ return mptr;}
private:
    T *mptr; //指向资源的指针
    RefCnt<T> *mpRefCnt; //指向该资源引用计数的指针
};
int main()
{
    /*
    带引用计数的智能指针share_ptr和weak_ptr
    带引用计树:多个指针指针可以管理同一个资源
    带引用计数:给每一个对象资源匹配一个引用计数
    智能指针-> 资源的时候->引用计数+1
    智能指针->不使用资源的时候——>引用计数+1 !=0 资源释放了
    */
   CSmartPtr<int> ptr1(new int);
   CSmartPtr<int> ptr2(ptr1);
   return 0;
}

交叉引用

在这里插入图片描述

#include<iostream>
#include<memory>
using namespace std;
// 强智能指针循环引用是什么问题?什么结果?怎么解决?
// share_ptr 强智能指针会改变引用计数
// weak_ptr弱智能指针 不会改变引用计数
class B;
class A
{
public:
    A()
    {cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}
    shared_ptr<B> _ptrb;
};
class B
{
public:
    B()
    {cout<<"B()"<<endl;}
    ~B(){cout<<"~B()"<<endl;}
    shared_ptr<A> _ptra;
};
int main(void)
{
    shared_ptr<A> pa(new A());
    shared_ptr<B> pb(new B());
      
    pa->_ptrb=pb;
    pb->_ptra=pa;
    cout<<pa.use_count()<<endl; //2
    cout<<pa.use_count()<<endl; //2
    return 0;
}

解决

#include<iostream>
#include<memory>
using namespace std;
// 强智能指针循环引用是什么问题?什么结果?怎么解决?
// share_ptr 强智能指针会改变引用计数
// weak_ptr弱智能指针 不会改变引用计数
class B;
class A
{
public:
    A()
    {cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}
    void testA() {cout<<"非常好用的方法"<<endl;}
    weak_ptr<B> _ptrb;
};
class B
{
public:
    B()
    {cout<<"B()"<<endl;}
    ~B(){cout<<"~B()"<<endl;}
    void func()
    {
        shared_ptr<A> ps=_ptra.lock(); //提升方法
        if(ps!=nullptr)
        {
            // _ptra->testA();
            shared_ptr<A> ps=_ptra.lock(); //提升方法
            ps->testA();
        }
    }
    weak_ptr<A> _ptra;
};
int main(void)
{
    shared_ptr<A> pa(new A());
    shared_ptr<B> pb(new B());
      
    pa->_ptrb=pb;
    pb->_ptra=pa;
    cout<<pa.use_count()<<endl; //1
    cout<<pa.use_count()<<endl; //1
    return 0;
}

解决交叉引用

#include<iostream>
#include<memory>
#include<thread>
using namespace std;
// 强智能指针循环引用是什么问题?什么结果?怎么解决?
// share_ptr 强智能指针会改变引用计数
// weak_ptr弱智能指针 不会改变引用计数
class A
{
public:
    A()
    {cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}
    void testA() {cout<<"非常好用的方法"<<endl;}
};
void handler01(weak_ptr<A> pw)
{
    std::this_thread::sleep_for(std::chrono::seconds(2));
    shared_ptr<A> sp=pw.lock();
    if(sp!=nullptr)
    {
        sp->testA();
    }
    else{
        cout<<"A对象已经析构不能访问"<<endl;
    }
}
// main线程
int main()
{
    {
        shared_ptr<A> p(new A());
        thread t1(handler01,weak_ptr<A>(p));
        t1.detach();
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }
     std::this_thread::sleep_for(std::chrono::seconds(4));
//  阻塞等待子线程结束
    // t1.join();
    return 0;
}

在这里插入图片描述

删除器

在这里插入图片描述

#include<iostream>
#include<memory>
#include<thread>
#include<functional>
using namespace std;
template<typename T>
class MyDeletor
{
public:
    void operator()(T *ptr) const
    {
        cout<<"call MyDeletor operator[]"<<endl;
        delete []ptr;
    }

};
template<typename T>
class MyFileDeletor
{
public:
    void operator()(T*ptr) const
    {
        cout<<"call MyfileDeletor.operator"<<endl;
        fclose(ptr);
    }
};
int main()
{
    unique_ptr<int,MyDeletor<int>> ptr1(new int[100]); //de;ete []ptr
    unique_ptr<FILE,MyFileDeletor<FILE>> ptr2(fopen("data.txt","w"));
    // lambda表达式
    unique_ptr<int,function<void(int*)>> ptr3(new int[100],[](int *p)->void{
        delete p;
    });
    unique_ptr<FILE,function<void (FILE*)>> ptr4(fopen("data1.txt","w"),[](FILE*p)->void{
        delete p;
    } ); 
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值