기존 스마트포인터들은 new[] 형식의 할당된 포인터는 제대로된 처리를 하지않습니다.
(boost 라이브러리나 기타 라이브러리에 이미 보완된 코드가 존재할 것 같은데, 저는 한번도 못봤네요.)
때문에 기존 스마트포인터를 new[] 형태로 사용할 경우엔 일반적으로 vector 컨테이너와 함께 사용합니다.
스마트포인터 소멸자의 처리에서 new[] 형식의 할당된 포인터는 delete[] 를 호출해야 하지만, 기존 스마트포인터는 delete 만 호출할 겁니다.
이런 정상적으로 해제되지 않은 메모리는 _CrtDumpMemoryLeaks() 로 메모리 누수 체크를 하면 정상적으로 탐지하지 못하게 됩니다.
그리하여 vector 까지 써가며 코드를 작성하는게 귀찮았기 때문에 간단하게 만들어본 클래스입니다.
namespace am
{
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private:
noncopyable(const noncopyable&);
noncopyable& operator=(const noncopyable&);
}; // class noncopyable
template<class R>
class safe_ptr : private noncopyable
{
private:
R* ptr_;
size_t cnt_;
public:
explicit safe_ptr(R* ptr = 0) throw()
{
if (ptr)
{
ptr_ = ptr;
cnt_ = _msize(ptr) / sizeof(R);
}
}
explicit safe_ptr(void* ptr) throw()
{
ptr_ = (R*)ptr;
cnt_ = 0;
}
~safe_ptr()
{
if (ptr_ && cnt_)
cnt_ == 1 ? delete ptr_ : delete[] ptr_;
ptr_ = nullptr;
}
R& operator*() const throw()
{
return *ptr_;
}
R* operator->() const throw()
{
return ptr_;
}
R& operator[](size_t n) const throw()
{
return ptr_[n];
}
R* get() const throw()
{
return ptr_;
}
size_t get_size() const throw()
{
return cnt_;
}
bool empty() const throw()
{
return nullptr == ptr_;
}
}; // template<class R> class safe_ptr
} // namespace am