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()로만 가능하다.
'C,C++' 카테고리의 다른 글
[Effective C++]항목 15 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자. (0) | 2019.08.05 |
---|---|
[Effective C++] 항목 19 : 클래스 설계는 타입 설계와 똑같이 취급하자. (0) | 2019.08.01 |
[Effective C++] 항목 12 : 객체의 모든 부분을 빠짐없이 복사하자. (0) | 2019.07.30 |
[Effective C++] 항목 11 : operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자. (0) | 2019.07.25 |
[Effective C++] 항목 10 : 대입 연산자는 *this의 참조자를 반환하게 하자 (0) | 2019.07.24 |
댓글