기존 스마트포인터들은 new[] 형식의 할당된 포인터는 제대로된 처리를 하지않습니다.
(boost 라이브러리나 기타 라이브러리에 이미 보완된 코드가 존재할 것 같은데, 저는 한번도 못봤네요.)
때문에 기존 스마트포인터를 new[] 형태로 사용할 경우엔 일반적으로 vector 컨테이너와 함께 사용합니다.
스마트포인터 소멸자의 처리에서 new[] 형식의 할당된 포인터는 delete[] 를 호출해야 하지만, 기존 스마트포인터는 delete 만 호출할 겁니다.
이런 정상적으로 해제되지 않은 메모리는 _CrtDumpMemoryLeaks() 로 메모리 누수 체크를 하면 정상적으로 탐지하지 못하게 됩니다.
그리하여 vector 까지 써가며 코드를 작성하는게 귀찮았기 때문에 간단하게 만들어본 클래스입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 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 |