[置顶] 【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;
}
由于 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;
}
相关文章推荐
- [置顶] 【C++】 浅析异常
- [置顶] 【C++】 浅析深浅拷贝
- [置顶] 【C++】 双向链表.cpp
- [置顶] 【C++】 单链表 .cpp
- [置顶] 【C++】 复数类操作
- [置顶] 【c语言】 单链表
- [置顶] 【c语言】 单链表
- [置顶] 【C语言】 简易通讯录
- [置顶] 【C语言】 动态开辟二维数组
- [置顶] 【C语言】 使用回调函数实现冒泡排序
- [置顶] 【C语言】 函数指针小谈
- [置顶] 【C语言】 模拟计算器
- [置顶] 【C语言】 浅谈指针
- [置顶] 【C语言】 检测大小端存储
- [置顶] 【C语言】 实现strncpy,strncat,strncmp
- [置顶] 【C语言】 实现memset
- [置顶] 【C语言】 实现memcmp
- [置顶] 【C语言】 实现memmove
- [置顶] 【C语言】 冒泡排序子例
- [置顶] 【C语言】 实现memcpy