条款13 以对象管理资源
对象管理资源,防止资源泄露
举个最简单例子:
void func()
{
value_type *p = createMemory();
...
delete p;
}
假如中间出现了异常或者有return等。很有可能就忘记释放内存。
务必遵守以下几点:
- 获取到资源后立即放入管理对象
- 管理对象运用析构函数确保资源被释放
TR1的tr1::shared_ptr就是一个很好地资源管理类,也称为“引用计数型智慧指针”也就是大家常说的智能指针。
刚刚代码就可以更改为:
void func()
{
std::tr1::share_ptr<value_type> p(createMemory());
...
delete p;
}
另一种年代比较久远的智能指针是auto_ptr由于它没有引用计数功能,所以不作讲解。
下面自己实现一个shared_ptr加深理解
自己实现智能指针
template<typename T>
class MySharedPtr
{
public:
MySharedPtr(T* memory = nullptr) : m_ptr(memory), m_count(new size_t(1)){}
MySharedPtr& operator=(MySharedPtr& r)
{
if(this != &r && (*this).m_ptr != r.m_ptr)
{
MySharedPtr temp(r);
swap(*this, temp);
}
return *this;
}
MySharedPtr(MySharedPtr& r) : m_ptr(r.m_ptr), m_count(r.m_count)
{
++*r.m_count;
}
T& operator*() const
{
return *m_ptr;
}
T* operator->() const
{
return m_ptr;
}
//获取原始指针
T* get()
{
return m_ptr;
}
~MySharedPtr()
{
reset();
}
//释放所有资源
void reset()
{
--*m_count;
if(*m_count == 0)
{
delete m_ptr;
m_ptr = nullptr;
delete m_count;
m_count = nullptr;
cout <<"delete memory"<<endl;
}
}
//检查是否独占内存
bool unique()const
{
return *m_count;
}
//重载输出
friend ostream& operator <<(ostream& out, const MySharedPtr<T>& obj)
{
out << *obj.m_ptr;
return out;
}
private:
static void swap(MySharedPtr& l, MySharedPtr& r)
{
std::swap(l.m_ptr, r.m_ptr);
std::swap(l.m_count, r.m_count);
}
private:
size_t* m_count;
T* m_ptr;
};