Home // Blog
Home // Notice
Home // Tag Log
Home // Location Log
Home // Media Log
Home // GuestBook
C++ 이야기 아홉번째: Array를 가리킬 수 있는 Smart Pointer
Posted at 2007. 5. 14. 00:19 //
in S/W개발/C++ 이야기 //
by
scoped_array와 shared_array는 그 이름에서 쉽게 알 수 있듯이 scoped_ptr과 shared_ptr 의 array 버전입니다. 왜 굳이 scoped_ptr과 shared_ptr 하나로 그냥 객체 하나와 array 하나를 가리키지 않고, scoped_array 와 shared_array 라는 걸 따로 두었을까요 ?
그 이유는 C++ 이야기 세번째: new와 delete 라는 글을 보면 금방 아실 수 있습니다. 거기에 나왔던 내용을 다시 한 번 정리하자면,
* new: 객체 하나를 동적으로 할당하고, 초기화시켜 줍니다.라고 할 수 있습니다.
* delete: 객체 하나를 소멸시키고, 삭제합니다.
* new []: 객체의 배열을 동적으로 할당하고, 하나 하나를 초기화시켜 줍니다.
* delete []: 객체의 배열 하나 하나의 요소를 소멸시키고, 배열을 삭제합니다.
......
"new 로 할당했으면 delete 로 해제, new [] 로 할당했으면 delete []로 해제하시라"
그러니, 그냥 객체 하나만 가리키는 경우와 객체의 배열을 가리키는 smart pointer 클래스를 따로 둘 수 밖에 없는 것이겠지요. 물론 이런 방법외에도 scoped_ptr이나 shared_ptr이 vector 표준 container를 가리키도록 한다면 거의 같은 효과를 낼 수 있겠지만, vector 와 같이 dynamic 하게 array의 크기가 늘었다 줄었다 할 필요가 없는 간단한 경우라면 vector의 overhead를 부담할 필요가 없을 것입니다. 그런 경우에는 당연히 scoped_array 와 shared_array가 훨씬 좋겠지요.
scoped_array는 scoped_ptr과 마찬가지로 noncopyable 에서 상속받으므로 복사할 수가 없고, scoped_array 객체가 소멸될 때 scoped_array가 가리키는 객체도 함께 소멸됩니다. 즉, scoped_ptr과 용도는 동일한데, array를 가리키는데 사용된다는 점만 다릅니다. array 를 가리키는데 사용되기 때문에 scoped_ptr 과는 한 가지 다른 점이 있습니다. 그건 아래에 보시는 대로 operator [] 가 override되어 있다는 것입니다.
namespace boost {
template<class T> class scoped_array : noncopyable {
public:
typedef T element_type;
explicit scoped_array(T * p = 0); // never throws
~scoped_array(); // never throws
void reset(T * p = 0); // never throws
T & operator[](std::ptrdiff_t i) const; // never throws
T * get() const; // never throws
operator unspecified-bool-type() const; // never throws
void swap(scoped_array & b); // never throws
};
// never throws
template<class T>
void swap(scoped_array<T> & a, scoped_array<T> & b);
}
array의 element를 가리킬 수 있게 하려면 당연한 것이겠지요.
그리고, shared_array는 shared_ptr의 array 버전이라고 생각하시면 되구요, 그 용도는 shared_ptr과 같습니다. 한 가지 다른 점은 이미 예상하셨겠지만 다음과 같이 operator []가 override되어 있다는 점입니다.
namespace boost {
template<class T> class shared_array {
public:
typedef T element_type;
explicit shared_array(T * p = 0);
template<class D> shared_array(T * p, D d);
~shared_array(); // never throws
shared_array(shared_array const & r); // never throws
shared_array & operator=(shared_array const & r); // never throws
void reset(T * p = 0);
template<class D> void reset(T * p, D d);
T & operator[](std::ptrdiff_t i) const() const; // never throws
T * get() const; // never throws
bool unique() const; // never throws
long use_count() const; // never throws
operator unspecified-bool-type() const; // never throws
void swap(shared_array<T> & b); // never throws
};
// all never throws
template<class T>
bool operator==(shared_array<T> const & a,
shared_array<T> const & b);
template<class T>
bool operator!=(shared_array<T> const & a,
shared_array<T> const & b);
template<class T>
bool operator<(shared_array<T> const & a,
shared_array<T> const & b);
template<class T>
void swap(shared_array<T> & a, shared_array<T> & b);
}
이쯤에서 scoped_array와 shared_array에 대한 소개는 마치구요. 이 정도 소개드리면 객체 array를 scoped_ptr 이나 shared_ptr로 가리키는 것이 마치 new [] 로 할당한 객체 array를 delete [] 가 아닌 delete 로 삭제하는 것과 비슷한 오류라는 것을 이해하실 거라고 생각하고, 저는 이만 물러 가겠습니다.
다음에는 최근 C++ library extension 으로 제안된 TR1에 대해서 소개해 드리도록 하겠습니다. 이전에 몇 가지 소개해드린 것들 중에 이미 TR1에 속해 있는 것들도 상당수 있습니다.
다음 글도 기대해 주시고, 앞으로 C++ 시리즈가 쭉~ 계속되기를 원하신다면 댓글 달아 주시는 센스 잊지 마세요~ 앞으로도 관심 있게 읽어 주시고, 소프트웨어 관련된 저의 다른 글들도 참고로 읽어 보세요.
소프트웨어는 soft 해야 제 맛이다
Flexible한 S/W 작성하기
소스코드 복사의 위험성
C++ 이야기 첫번째: auto_ptr 템플릿 클래스 소개
C++ 이야기 두번째: auto_ptr의 두 얼굴
C++ 이야기 세번째: new와 delete
C++ 이야기 네번째: boost::shared_ptr 소개
C++ 이야기 다섯번째: 내 객체 복사하지마!
C++ 이야기 여섯번째: 기본기 다지기(bool타입에 관하여)
C++ 이야기 일곱번째: auto_ptr을 표준 컨테이너에 담지 말라
Embedded System 의 Stack Size 제한
C++ 이야기 여덟번째: boost::scoped_ptr 소개