您的位置:首页 > 运维架构

智能指针AutoPtr,ScopedPtr的模拟实现

2017-04-13 16:44 302 查看
智能指针: 所谓智能指针就是智能/⾃动化的管理指针所指向的动态资源的释放

为什么我们会有智能指针呢,我们通过下面的代码来看一下

void DoSomeThing ()
{
throw 2 ;
}
void Test2 ()
{
int* p1 = new int(2);
try
{
DoSomeThing();
}
catch(...)
{

throw;
}
delete p1 ;
}


我们下来可以尝试一下这个程序,尝试过的同学会知道这个程序在调试中没有报错,但是在运行的时候就会崩溃,那么这个是什么原因呢?

原因是我们在开辟了空间遇到了异常,throw是抛出异常,我们都知道在抛出异常后面的代码都不会继续执行,所以这里我们的错误在于没有释放空间

这里我们就要使用智能指针首先我们介绍一下

智能指针是一个模版类

它的目的:

1,管理指针指向对象的释放间隔

2,可以像指针一样用起来(这里我们会用到重载)

我们先说一下RAII

RAII(Resource Acquisition Is Initialization)

资源分配即初始化,定义⼀个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。

下来我们来模拟实现一下AutoPtr

template<class T>
class AutoPtr
{
public:
AutoPtr(T *ptr)
:_ptr(ptr)

T& operator*()
{
return *_ptr;
}
T *operator->()
{
return _ptr;
}
~AutoPtr()
{
delete _ptr;
}
protected:
T *ptr;
};


总结AutoPtr:

1,管理指针指向对象的释放

PAII——>(自动)析构函数释放管理对象

2,operator*,operator->的重载让我们像原生指针一样使用智能指针访问管理对象

但是同时它也是有缺点的

AutoPtr<int>ap1(new int);
AutoPtr<int>ap2(ap1);


我们会发现同一块内存释放了两次,程序挂了(解决方法:管理员的转移,但是这个是有问题的)

在这里AutoPtr用了管理员转移的方法来解决问题

AutoPtr(AutoPtr<T>& ap)
{
//管理权的转移
this->_ptr=ap._ptr;
ap._ptr=NULL;
}


但是对于管理权的转移这种方法是存在缺陷的,我们尽量不要使用

下来我们引用了ScopedPtr 它的特点是简单粗暴——防拷贝(只声明不定义)

下来我们来模拟实现一下ScopedPtr

template<class T>
class ScopedPtr
{
public:
ScopedPtr(T*_ptr)
:_ptr(ptr)
{}

~ScopedPtr()
{
delete _ptr;
}
T &operator*()
{
return *_ptr;
}
T*operator->()
{
return _ptr;
}
//我们把它声明为保护,是防止对它的调用
protected:
ScopePtr(ScopePtr<T> & s);
ScopedPtr<T> operator=(ScopedPtr<T>&s);

protected:
T*_ptr;
};


protected:
ScopePtr(ScopePtr<T> & s);
ScopedPtr<T> operator=(ScopedPtr<T>&s);
//对于这一块的代码,我们把它声明为保护,是防止对它的调用,也就是防拷贝
//防拷贝是只声明不定义,并且要声明为私有或者保护,避免别人对它调用。


但是我们的ScopedPtr也是有缺陷的——功能不全

那么我们引入了share_ptr,在下一篇博客我们会模拟实现SharePtr.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: