您的位置:首页 > 编程语言 > C语言/C++

[置顶] 【C++】 浅析智能指针

2016-05-26 12:25 501 查看
引言:

由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见。

RAII(Resource Acquisition Is Initialization)
资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。
所谓智能指针就是智能/自动化的管理指针所指向的动态资源的释放。
STL--auto_ptr
Boost库的智能指针(ps:新的C++11标准中已经引入了unique_ptr/shared_ptr/weak_ptr)




在这里,对于aut_optr,scoped_ptr , shared_ptr 进行剖析
一. aut_optr
std::auto_ptr 属于 STL,当然在 namespace std 中,包含头文件 #include<memory> 便可以使用。std::auto_ptr 能够方便的管理单个堆内存对象。为了解决单个对象被重复释放多次的情况,我们使用的aut_optr的目的就是转移权限,顾名思义就是说再拷贝构造新的对象时,由于此时有两个对象指向同一块空间,所以将原来的指针赋NULL,然后将这块空间的所有权交给新的对象指针。
对应代码:<AutoPtr>
[code=cpp;toolbar:false">#include<iostream>
using namespace std;
 
template<class T>
class AutoPtr
{
public:
    AutoPtr(T* ptr)
    :_ptr(ptr)
    {}
 
    AutoPtr()
    :_ptr(NULL)
    {}
 
    AutoPtr<T>(AutoPtr<T>& ap)   //权限转移
        : _ptr(ap._ptr)
    {
        ap._ptr = NULL;
    }
 
    AutoPtr<T>& operator=(AutoPtr<T>& ap)
    {
        if (&ap != this)
        {
            delete _ptr;
            _ptr = ap._ptr;
            ap._ptr = NULL;   //权限转移
        }
        return *this;
    }
 
    ~AutoPtr()
    {
        if (_ptr)
        {
            delete _ptr;
            _ptr = NULL;
        }
    }
 
    T& operator*()
    {
        return *_ptr;
    }
 
private:
    T* _ptr;
};
 
void Test()
{
    AutoPtr<int> ap1(new int(2));
    AutoPtr<int> ap2 = ap1;
    AutoPtr<int> ap3(new int(3));
    ap3 = ap1;
}
 
int main()
{
    Test();
    return 0;
}#include<iostream>
using namespace std;
 
template<class T>
class SharedPtr
{
public:
    SharedPtr(T* ptr)
        :_ptr(ptr)
        , _pCount(new long(1))
    {}
 
    SharedPtr()
        :_ptr(NULL)
        , _pCount(new long(1))
    {}
 
    SharedPtr<T>(const SharedPtr<T>& sp)
        : _ptr(sp._ptr)
        , _pCount(sp._pCount)
    {
        ++(*_pCount);
    }
 
    SharedPtr<T>& operator=(const SharedPtr<T>& sp)
    {
        if (&sp != this)
        {
            if (--(*_pCount) == 0) // 减到0释放对象一次
            {
                delete _ptr;
                delete _pCount;
            }
            _ptr = sp._ptr;
            _pCount = sp._pCount;
            ++(*_pCount);
        }
        return *this;
    }
 
    ~SharedPtr()
    {
        if (_ptr)
        {
            if (--(*_pCount) == 0)
            {
                delete _ptr;
                delete _pCount;
            }
        }
    }
 
    T& operator*()
    {
        return *_ptr;
    }
    
    T* operator->()
    {
        return _ptr;
    }
 
    long GetCount()
    {
        return *(_pCount);
    }
 
    T* GetPtr()
    {
        return _ptr;
    }
 
private:
    T* _ptr;
    long* _pCount;
};
 
 
void Test()
{
    SharedPtr<int> sp1 = new int(1);
    SharedPtr<int> sp2 = sp1;
    SharedPtr<int> sp3 = new int(2);
    sp3 = sp1;
}
 
 
int main()
{
    Test();

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: