본문 바로가기
C,C++

[Effective C++] 항목 13 : 자원 관리에는 객체가 그만!

by matters_ 2019. 7. 31.

auto_ptr과 tr1::shared_ptr에 대해서 서술되어 있는데 현재 auto_ptr은 사라진 상태이므로 그냥 그 이후에 적용된 스마트포인터 중 유니크 포인터에 대해서 서술하겠다.

auto_ptr이 왜 사라진 이유는 배열의 포인터를 해제할 때 배열 객체가 모두 제대로 해제되지 않는다는 것과 복사 대입 연산시 실제로는 복사가 되지 않는다는 것이다.

이러한 문제점들을 보완하기 위해 C++11 표준에서는 새로운 스마트 포인터들이 포함됐다. 그리고 이동 시맨틱이 추가되었다. 이동 시맨틱은 객체를 복사하지 않고 이동시킨다. 이동 후에 객체의 소유권은 당연히 대입된 쪽이 가진다. 복사 시맨틱일 경우, STL 컨테이너 중 리스트나 벡터는 동적 배열이기 때문에 상황에 따라 그 메모리 크기가 두배까지 늘어난다. 그러고 나선 정작 원본은 해제시켜버린다. 이런 일련의 동작들이 메모리를 낭비하고 성능을 저하시키기 때문에 이동 시맨틱은 꼭 필요한 것이었다.

std::unique_ptr는 다음과 같은 상황이 발생하면 관련된 deleter를 통해 소멸한다.

  • unique_ptr 개체가 파괴될 
  • unique_ptr 개체가 다른 pointer 할당될 (operator= 또는 reset() 이용하여

std::unique_ptr 다음 두가지 형태가 있다.

  • 하나의 object(new 할당된) 관리
  • 동적으로 할당된 object 배열(new[] 할당된) 관리

 이동 생성자와 이동 할당자는 지원한다.

	unique_ptr<int> p1(new int(5));

	unique_ptr<int> p2(new int(4));

	unique_ptr<int> p3(std::move(p1));

	unique_ptr<int> p4 = std::move(p1);

그러나 복사 생성자와 복사 할당자는 지원하지 않아서 unique_ptr 함수의 인자로 (by value) 전달하거나 return (by value)으로 사용할  없다.

        unique_ptr<int> p3(p1);   // Error

        unique_ptr<int> p4 = p1;  // Error

get()으로 raw pointer를 얻을 수 있고 reset()으로 해제시키며 이동은 std::move()로만 가능하다. 

댓글