C++编程调试秘笈----读书笔记
造成内存泄露的大多原因都是因为分配了空间但是没有进行释放的结果。但是这样并不会引发错误
一般来说,解决这个问题的有很多种方法,比如com、boost的智能指针,都在某一种情况下对这种问题提供了解决方案。下面来探讨两种情况的指针
但我们可以建立一个自己的smart point,同时也需要考虑三种情况:
1.是否允许对smart point进行复制,如果是,在smart point中的多份拷贝中,到底有哪一个负责删除它们共同指向的对象(com是最后一个)
2.smart point是否表示指向一个对象的指针,或者表示指向一个对象数组的指针(即它应该使用带方括号的还是不带方括号的delete操作符)
3.smart point是否对应于一个常量指针或一个非常量指针
出于上述的三个情况,有以下两种smart point可以满足:
1.引用计数指针(又称共享指针,也就是com中的smart point)
2.作用域指针
这两种smart point的不同之处在于引用计数指针可以被复制,而作用域指针不能被复制。但是,作用域指针的效率更高。
引用计数指针:
scpp_refcountptr.h:
[cpp]
#ifndef __SCCP_SCOPEDPTR_H__
#define __SCCP_SCOPEDPTR_H__
#include "scpp_assert.h"
namespace scpp
{
template <typename T>
class RefCountPtr
{
public:
explicit RefCountPtr(T* p = NULL)
{
Create(p);
}
RefCountPtr(const RefCountPtr<T>& rhs)
{
Copy(rhs);
}
RefCountPtr<T>& operator = (const RefCountPtr<T>& rhs)
{
if (ptr_ != rhs.ptr_)
{
Kill();
Copy(rhs);
}
return *this;
}
RefCountPtr<T>& operator = (T *p)
{
if (ptr_ != p)
{
Kill();
Create(p);
}
return *this;
}
~RefCountPtr()
{
std::cout << "kill" << std::endl;
Kill();
}
public:
T* Get() const { return ptr_; }
T* operator ->() const
{
std::cout << "in this" << std::endl;
SCPP_TEST_ASSERT(ptr_ != NULL, "Attempt to use operator -> on NULL pointer.");
return ptr_;
}
T& operator *() const
{
SCPP_TEST_ASSERT(ptr_ != NULL, "Attempt to use operator -> on NULL pointer.");
return *ptr_;
}
private:
void Create(T* p)
{
ptr_ = p;
if (ptr_ != NULL)
{
refCount_ = new int;
*refCount_ = 1;
}
else
{
refCount_ = NULL;
}
}
void Copy(const RefCountPtr<T>& rhs)
{
ptr_ = rhs.ptr_;
refCount_ = rhs.refCount_;
if (refCount_ != NULL)
{
++(*refCount_);
}
}
void Kill()
{
if (refCount_ != NULL)
{
if (--(*refCount_) == 0)
{
delete ptr_;
ptr_ = NULL;
delete refCount_;
refCount_ = NULL;
}
}
}
private:
T* ptr_;
int* refCount_;
};
} // namespace scpp
#endif // __SCCP_SCOPEDPTR_H__
测试代码(vs2012+win7环境):
[cpp]
// debug.cpp : 定义控制台应用程序的入口点。
//
#include &qu
补充:软件开发 , C++ ,