std :: auto_ptr에서 std :: unique_ptr로


185

새로운 표준이 등장함에 따라 (그리고 일부 컴파일러에서 이미 사용 가능한 부분), 새로운 유형 std::unique_ptr은의 대체품으로 간주됩니다 std::auto_ptr.

사용법이 정확히 겹치므로 (내 코드에서 전역 찾기 / 바꾸기를 수행 할 수는 있지만 (그렇지 않은 경우) 그렇지 않은 경우) 설명서를 읽을 때 명확하지 않은 몇 가지 차이점을 알고 있어야합니까?

또한 그것이 직접 대체라면 왜 개선하지 않고 새로운 이름을 부여 std::auto_ptr합니까?

답변:


219

auto_ptr알려진 결과를 사용하여 복사 할 수 있기 때문에 전역 찾기 / 바꾸기를 수행 할 수 없지만 unique_ptr이동 만 할 수 있습니다. 보이는 것

std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p; 

최소한 이런 식으로되어야합니다

std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);

다른 차이점 unique_ptr은 배열을 올바르게 처리 할 수 ​​있습니다 (호출 delete[]하는 동안 auto_ptr호출하려고 시도합니다) delete.


101
반면 에이 찾기 / 바꾸기를 수행하면 컴파일 오류 만 발생하며 볼 수있는 한 코드가 자동으로 중단되지 않습니다. 따라서 나중에 컴파일 오류를 수동으로 수정하면 안전합니다
jalf

7
@ jalf : 실제로, auto_ptrs와 UB로 unique_ptrs로 잘 정의 된 카운터 예제를 생각할 수 없습니다.
Cubbi

1
그래서 그것은 unique_ptr이 auto_ptr의 향상 인 것처럼 보입니다 : 배열 지원 및 모호함 제거
Baiyan Huang

92

std::auto_ptrstd::unique_ptrsomeways 등의 교체에 드롭 호환되지 않습니다. 따라서 찾기 / 바꾸기만으로는 충분하지 않습니다. 그러나 컴파일 오류를 통해 찾기 / 바꾸기 작업 후 이상한 코너 경우를 제외한 모든 것을 수정해야합니다. 대부분의 컴파일 오류에는을 추가해야합니다 std::move.

  • 함수 범위 변수 :
    다른 함수에 값으로 전달하지 않는 한 100 % 호환됩니다.
  • 반환 유형 :
    100 % 호환되지 않지만 99 % 호환은 잘못되지 않습니다.
  • 값별 함수 매개 변수 :
    한 가지 경고와 100 % 호환되며 호출을 unique_ptr통과해야합니다 std::move. 컴파일러가 제대로 이해하지 못하면 불평하기 때문에 이것은 간단합니다.
  • 기준에 따른 기능 파라미터 :
    100 % 호환.
  • 클래스 멤버 변수 :
    이것은 까다 롭습니다. std::auto_ptrs 복사 의미론은 악하다. 수업이 복사를 허용하지 않으면 std::unique_ptr대체품이 떨어집니다. 그러나 클래스에 합리적인 카피 의미를 주려고하면 std::auto_ptr처리 코드 를 변경해야 합니다. 컴파일러가 제대로 이해하지 못하면 불만을 표시하므로 간단합니다. 특별한 코드 없이std::auto_ptr 멤버 와 함께 수업을 복사 할 수 있다면 부끄러운 일과 행운을 빕니다.

요약 std::unique_ptr하면 깨지지 않습니다 std::auto_ptr. 컴파일 타임에을 사용할 때 종종 오류였던 동작을 허용하지 않습니다 std::auto_ptr. 따라서 std::auto_ptr필요한 관리와 함께 사용한다면 std::unique_ptr간단하게 전환 할 수 있습니다. std::auto_ptr의 이상한 행동 에 의존했다면 어쨌든 코드를 리팩터링해야합니다.


8
"어쨌든 코드를 리팩터링해야합니다"+1 auto_ptrs는 20.4.5 / 3가 좋은 것을 말한 것에 대해서만 좋습니다.
Cubbi

8
코드에서 auto_ptr을 unique_ptr로 바꾸고 컴파일 오류를 수정해야한다는 것을 추가하십시오. 이것이 얼마나 많은 버그를 발견했는지 놀라게 될 것입니다.
Bartosz Milewski 23시 07 분

36

AFAIK unique_ptr는 직접 교체가 아닙니다. 그것이 해결하는 주요 결함은 내재적 소유권 이전입니다.

std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership

std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly

반면에 unique_ptr완전히 새로운 기능을 갖습니다. 컨테이너에 저장할 수 있습니다.


8
Scott Meyers는 또한 "Effective C ++"(제 3 판) 항목 13 (64 페이지)에서 STL 컨테이너의 내용에 "일반"복사 동작이 필요하므로 컨테이너는 auto_ptr허용되지 않는다고 언급했습니다.
Qiang Xu

31

Herb Sutter는 GotW # 89 에 대한 훌륭한 설명을 제공합니다 .

auto_ptr과의 거래는 무엇입니까? auto_ptr은 C ++이 이동 의미론을 갖기 전에 unique_ptr을 작성하려는 용감한 시도로 가장 자선 적으로 특징이 있습니다. auto_ptr은 이제 더 이상 사용되지 않으며 새 코드에서 사용해서는 안됩니다.

기존 코드베이스에 auto_ptr이있는 경우 전역 검색 및 auto_ptr을 unique_ptr로 대체하십시오. 대부분의 사용은 동일하게 작동하며, 컴파일 타임 오류로 노출되거나 자신이 모르는 버그를 수정 (조용히) 할 수 있습니다.

다시 말해, 전역 검색 및 교체는 코드를 일시적으로 "중단"할 수 있지만 어쨌든 코드를 수정해야합니다.


훌륭한 링크. 고마워요!
fotNelton
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.