[STL] 3. unique_ptr (2/2)

C++0x 2010. 8. 4. 12:00 Posted by 알 수 없는 사용자

안녕하세요. 지난 글에 이어 unique_ptr에 대해서 소개드리겠습니다.

auto_ptr의 완벽한 대체자 혹은 그 이상 

앞선 글에서 설명드렸듯이 unique_ptr은 auto_ptr이 deprecation으로 결정되면서 그 대체자 로서 제안되게 되었습니다. 필연적으로 auto_ptr의 모든 기능을 포함하고 있으며, 문법 또한 같습니다. 단, auto_ptr이 deprecation으로 결정되게 된 원인이었던 복사 문법을 제외됩니다.
아래 예제 코드는 auto_ptr의 기본적인 동작이 unique_ptr에서도 구현되어 있음을 보여줍니다.

  1     // 기본 생성자
  2     auto_ptr<int> ap;
  3     unique_ptr<int> up;
  4     // 포인터 생성자
  5     auto_ptr<int> autoPtr(new int);
  6     unique_ptr<int> uniquePtr(new int);
  7     // 역참조
  8     *autoPtr = 1;
  9     *uniquePtr = 2;
 10     // 초기화
 11     autoPtr.reset();
 12     uniquePtr.reset();

하지만 아래와 같은 문법에서 차이가 생깁니다.


  1 	auto_ptr<int> ap1(new int);
  2 	auto_ptr<int> ap2 = ap1; // OK
  3 	unique_ptr<int> up1(new int);
  4 	unique_ptr<int> up2(up1); // 컴파일 에러
  5 	unique_ptr<int> up2 = up1; // 컴파일 에러

 이 코드를 실행시켜보면, 4번째 줄에서 lvalue로 부터의 복사 생성자에서 에러가 발생합니다. 또한 5번째 줄에서 unique_ptr에 대한 복사 문법에 대한 컴파일 에러가 발생하는 것을 볼 수 있을 겁니다. 위의 코드를 올바르게 수정하면 다음과 같습니다.

  1 	unique_ptr<int> up1(new int);
  2 	unique_ptr<int> up2 = move(up1); // OK

삭제자(deleter) 지정하기

 특정한 삭제자 함수를 지정하지 않고 unique_ptr을 선언하는 경우에, unique_ptr은 객체가 new로 생성되었을 것을 가정하고 delete를 호출합니다. 하지만 unique_ptr을 선언할 때에 삭제자 함수를 특정함으로써 이를 바꿀 수 있습니다. 예를 들어, malloc으로 선언된 객체는 delete가 아닌 free로 삭제해야 합니다. free를 삭제자로 지정하는 방법은 아래와 같습니다.

  1 	int* intPtr = (int*)malloc(sizeof(int));
  2 	unique_ptr<int, void (*)(void*)> deleterTest(intPtr, std::free);

배열 객체 다루기

 unique_ptr에서는 배열 객체를 다룰 수 있도록 인터페이스를 추가하였습니다. 다음의 코드를 먼저 보겠습니다.


  1 	unique_ptr <int[]> intarr (new int[4]); //array version of unique_ptr
  2 	intarr[0]=10;
  3 	intarr[1]=20;
  4 	intarr[2]=30;
  5 	intarr[3]=40;

 intarr 객체는 int의 배열을 가지는 unique_ptr입니다. 하지만 [] 연산자를 구현하여 저장된 배열에 직접 접근할 수 있는 인터페이스를 구현되어 있습니다. 이 경우에, 선언부(줄 1)의 template에 들어간 []가 배열 객체를 다루는 unique_ptr임을 알려주게 됩니다.
 또한 위의 삭제자 지정하기에서 기본 삭제자가 delete가 된다고 했는데, 배열 객체를 다루는 unique_ptr은 delete []가 기본 삭제자가 됩니다.

참고 :
http://msdn.microsoft.com/en-us/library/ee410601.aspx
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=401
http://www.devx.com/cplus/10MinuteSolution/39071/1954