C++ — 智能指针一

RAII

资源获得及初始化,获得资源马上进行初始化
是一种利用对象生命周期来控制程序资源(如内存、文件句 柄、网络连接、互斥量等等)的简单技术。
在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。

//智能指针专门用来管理动态开辟的空间
//RAII不等价于只能指针
//RAII是解决问题的思想
//智能指针是RAII思想的一种实现
template<class T>
class SmartPtr
{
public:
	SmartPtr(T* ptr)	//在构造函数时保存动态开辟空间的指针
		:_ptr(ptr)
	{
	}
	~SmartPtr()	//在析构函数中释放
	{
		delete _ptr;
	}
    T* get()
    {
        return _ptr;
    }
    T* operator*() 
    {
         return *_ptr;
    }
     T*   operator->()    
    {
         return _ptr;
    }
private:
	T* _ptr;
};
//托管
SmartPtr<int*> sp(new int);   //这样在外界无法访问,需要重载 operator*() operator->()
//这样,就算抛异常导致结束时未释放资源,函数结束销毁对象时会自动调用析构函数

auto_ptr

//模仿实现
template<class T>
class auto_ptr   //C++98
{
public:
    auto_ptr(T* ptr)	//在构造函数时保存动态开辟空间的指针
		:_ptr(ptr)
	{
	}
	~auto_ptr()	//在析构函数中释放
	{
		delete _ptr;
	}
     T* operator*() 
    {
         return *_ptr;
    }
     T* operator->()    
    {
         return _ptr;
    }
    
    //管理权转移
    auto_ptr(const auto_ptr<T>& ap)
         :_ptr(ap._ptr)  // 这样就解决了一块空间被多个对象使用而造成程序奔溃问题
    {
        ap._ptr = nullptr;    //把两个对象中的指针变为一个
    }
    auto_ptr<T>& operator=(const auto_ptr<T>& ap)
    {
        if(this != &ap) // 检测是否为自己给自己赋值
        {
            if(_ptr) // 释放当前对象中资源
            {
                delete _ptr;    //放置在赋值时这个对象本身就指向空间,赋值时而忘记释放
            }
            _ptr = ap._ptr;  // 转移资源到当前对象中
            ap._ptr = nullptr;
        }
        return *this;
    }
     //测试函数     
    void test_auto_ptr()
    {
        auto_ptr<int> ap1(new int);
        auto_ptr<int> ap2(ap1);        //不定义拷贝构造则浅拷贝,释放两次
       *ap1 = 10; //报错    访问空指针
        ap1 = ap3;    
    }
private:
    T* _ptr;
};

void test_auto_ptr()   
{
    //库中的auto_pr
    std::auto_ptr<int> ap1(new int);
    std::auto_ptr<int> ap2(ap1);,//多次释放
    *ap1 = 10; //崩溃, ap1已经成为nullptr
}

unique_ptr

//推荐使用
//简单粗暴,不允许拷贝
//是线程安全的,访问数据需要加锁,不会出现同时多线程使用
template<class T>
class unique_ptr
{
public:
    unique_ptr(T* ptr)	//在构造函数时保存动态开辟空间的指针
		:_ptr(ptr)
	{
	}
	~unique_ptr()	//在析构函数中释放
	{
		delete _ptr;
	}
     T* operator*() 
    {
         return *_ptr;
    }
     T* operator->()    
    {
         return _ptr;
    }
    //不允许拷贝和赋值
     C++98防拷贝的方式:只声明不实现+声明成私有
    // C++11防拷贝的方式:delete
    unique_ptr(const unique_ptr<T>& up) = delete;
    unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;
    //测试函数  
    void test_unique_ptr()    //自己实现
	{
    	std::unique_ptr<int> ap1(new int);
    	std::unique_ptr<int> ap2(ap1);        //报错,不能实现
	}
private:
        T* _ptr;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值