본문 바로가기

C++ Programming/STL

auto_ptr 클래스

1. auto_ptr클래스는 예외가 발생했을 경우 리소스릭을 피하기 위해 STL이 제공하는 스마트 포인터의 한 종류이다.
즉 자신이 가리키는 객체에 대한 소유자로서 행동하는 포인터이다. auto_ptr이 파괴된다면 소유하고 있던 객체도 자동으로 파괴되는 것이다.

통상적으로 auto_ptr클래스는 할당 연산자(=)를 통해서 초기화를 할 수 없다.

ex)

std::auto_ptr<classa>ptr1(new classa);
std::auto_ptr<classa>ptr2(new classa);

ptr2 = ptr1; //auto_ptr을 할당하면 ptr2가 소유한 객체를 소멸하게 되고 소유권이 ptr1에서 ptr2로 이전된다. 
               // ptr1 null상태

2. 위험성있는 코드
ex1)
template <class T>
 void bad_print(std::auto_ptr<T> p) //넘어온 인자의 소유권을 p가 가짐
 {
      ...
  } //종료하면서 p가 참조하는 객체를 삭제!! -> 심각한 런타임 에러

ex2)
          std::auto_ptr<int> f()
         {
const std::auto_ptr<int> p(new int); //소유권의 이전이 불가능
std::auto_ptr<int> q(new int); //소유권이전이 가능

*p = 42; //ok
 bad_print(p); //컴파일 에러
 *p = *q; //ok
 p = q; //컴파일 에러
 return p;//컴파일 에러

}

3. 클래스안에서 auto_ptr을 사용함으로써 리소스 릭을 피할 수 있다.
    일반적으로 생성자가 완전히 완료된 경우에만 소멸자가 호출된다는 사실을 명심!!
   class ClassB{
       private:
           ClassA* ptr1; //포인터 멤버
           ClassA* ptr2;
       public:
           //포인터를 초기화하는 생성자에서 두번째 new에서 예외를 던지면 리소스 릭의 원인이 될수 있다.
           ClassB(ClassA val1,ClassA val2)
                         : ptr1(new ClassA(val1)),ptr2(new ClassA(val2)){ }
          -> 개선
     class ClassB{
         private:
            const std::auto_ptr<ClassA>ptr1; //auto_ptr멤버
            const std::auto_ptr<ClassA>ptr2;
         public:
             ClassB(ClassA val1, ClassA val2)
                       : ptr1(new  ClassA(val1)),ptr2(new ClassA(val2)){ }


4. auto_ptr의 잘못된 사용사례
   a) auto_ptr은 소유권을 공유할 수 없다. 
       첫번째 auto_ptr이 삭제될때 객체가 파괴됨으로써 두번째 auto_ptr은 파괴된 객체를 가리킬수있따. 심각한 에러
   b) auto_ptr은 배열 타입을 지원하지 않는다.
       컨테이너 클래스를 쓰세요
   c) auto_ptr은 범용 스마트 포인터가 아니다.
       레퍼런스 카운트 개념을 사용하지 않는다.
   d) auto_ptr은 표준 컨테이너 클래스와 함께 사용될 수 없다. 
       컨테이너 클래스의 원소로써 auto_ptr은 절대로 사용해서는 안된다. 
   e) const auto_ptr으로 사용하라..