auto_ptr이 더 이상 사용되지 않는 이유는 무엇입니까?
auto_ptr
C ++ 11에서 더 이상 사용되지 않는다고 들었습니다 . 그 이유는 무엇입니까?
또한 나는 사이의 차이를 알고 싶습니다 auto_ptr
와 shared_ptr
.
에 대한 직접 대체 auto_ptr
(또는 어쨌든 가장 가까운 것)는 unique_ptr
. "문제"에 관해서는 매우 간단합니다. auto_ptr
할당되면 소유권을 이전하는 것입니다. unique_ptr
또한 소유권을 이전하지만 이동 의미론의 코드화와 rvalue 참조의 마법 덕분에 훨씬 더 자연스럽게 할 수 있습니다. 또한 표준 라이브러리의 나머지 부분과 "적합"합니다 (공평하게도 일부는 항상 복사를 요구하는 대신 이동 의미 체계를 수용하기 위해 라이브러리의 나머지 부분을 변경했기 때문입니다).
이름의 변경은 (IMO) 환영받는 것입니다. auto_ptr
자동화하려는 내용에 대해 실제로 많이 알려주지는 않지만 unique_ptr
제공된 내용에 대한 상당히 합리적인 (간결한 경우) 설명입니다.
기존 답변은 훌륭하지만 포인터의 PoV에서 찾았습니다. IMO, 이상적인 답변에는 사용자 / 프로그래머의 관점 답변이 있어야합니다.
먼저 (Jerry Coffin이 답변에서 지적했듯이)
- auto_ptr은 상황에 따라 shared_ptr 또는 unique_ptr로 대체 될 수 있습니다.
shared_ptr : 리소스 / 메모리 해제에 대해 걱정하고 객체를 AT-DIFFERENT 번 사용할 수있는 함수가 두 개 이상있는 경우 shared_ptr로 이동합니다.
DIFFERENT-Times에 의해 object-ptr이 여러 데이터 구조에 저장되고 나중에 액세스되는 상황을 생각해보십시오. 물론 다중 스레드가 또 다른 예입니다.
unique_ptr : 걱정되는 것이 메모리를 해제하는 것이고 객체에 대한 액세스가 SEQUENTIAL이면 unique_ptr로 이동하십시오.
SEQUENTIAL이란 어떤 지점에서든 하나의 컨텍스트에서 개체에 액세스 할 수 있음을 의미합니다. 예를 들어 생성자가 생성하고 생성 한 직후에 사용한 객체입니다. 생성 후 객체는 FIRST 데이터 구조에 저장됩니다 . 그런 다음 객체는 ONE 데이터 구조 후에 파괴되거나 SECOND 데이터 구조 로 이동됩니다 .
이 줄에서 공유 / 고유 _ptr을 스마트 포인터라고합니다. (auto_ptr도 스마트 포인터이지만 디자인의 결함으로 인해 더 이상 사용되지 않으며 다음 줄에서 지적 할 것이라고 생각하므로 스마트 포인터로 그룹화해서는 안됩니다.)
auto_ptr이 스마트 포인터를 선호하는 이유에 대한 가장 중요한 이유 중 하나는 할당 의미론 입니다. 그 이유가 아니라면 더 이상 사용하지 않는 대신 auto_ptr에 모든 새로운 이동 의미 체계를 추가했을 것입니다. 할당 의미론이 가장 싫어하는 기능 이었기 때문에 그들은 그 기능이 사라지기를 원했지만 그 의미를 사용하는 코드가 작성 되었기 때문에 (표준위원회는 변경할 수 없음), 대신 auto_ptr을 놓아야했습니다. 수정.
링크에서 : http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
unqiue_ptr에서 지원하는 할당의 종류
- 이동 할당 (1)
- 널 포인터 할당 (2)
- 형변환 할당 (3)
- 복사 할당 (삭제됨!) (4)
출처 : http://www.cplusplus.com/reference/memory/auto_ptr/operator=/
auto_ptr에서 지원하는 할당의 종류
- 복사 할당 (4) 범인
이제 복사 할당 자체가 왜 그렇게 싫어 졌는지에 대한 이유를 살펴보면 다음과 같은 이론이 있습니다.
- 모든 프로그래머가 책이나 표준을 읽는 것은 아닙니다.
- auto_ptr은 객체의 소유권을 약속합니다.
- 모든 프로그래머가 읽지 않는 auto_ptr의 little-* (말장난 의도) 절은 하나의 auto_ptr을 다른 것으로 할당하고 소유권을 이전합니다.
- 연구에 따르면이 동작은 모든 사용량의 3.1415926535 %를위한 것이며 다른 경우에는 의도하지 않은 것으로 나타났습니다.
의도하지 않은 동작은 정말 싫어하기 때문에 auto_ptr에 대한 싫어요.
(의도적으로 소유권을 이전하려는 프로그래머의 3.1415926536 %의 경우 C ++ 11은 std :: move ()를 제공하여 코드를 읽고 유지하려는 모든 인턴에게 의도를 명확히했습니다.)
shared_ptr
용기 안에 보관할 수 있습니다. auto_ptr
캔트.
BTW unique_ptr
는 실제로 직접 auto_ptr
대체품이며 std::auto_ptr
및 boost::scoped_ptr
.
차이점을 설명하는 또 다른 방법 ....
기능적으로 C ++ 11 std::unique_ptr
은 "고정"입니다 std::auto_ptr
. 둘 다-실행 중 어느 시점에서든-지적 대상 객체에 대해 단일 스마트 포인터 소유자가 있어야하는 경우에 적합합니다.
중요한 차이점은 =>
아래 줄에 표시된 만료되지 않는 다른 스마트 포인터의 복사 구성 또는 할당입니다 .
std::auto_ptr<T> ap(...);
std::auto_ptr<T> ap2(get_ap_to_T()); // take expiring ownership
=> std::auto_ptr<T> ap3(ap); // take un-expiring ownership ala ap3(ap.release());
ap->xyz; // oops... can still try to use ap, expecting it to be non-NULL
std::unique_ptr<T> up(...);
std::unique_ptr<T> up2(get_up_to_T()); // take expiring ownership
=> std::unique_ptr<T> up3(up); // COMPILE ERROR: can't take un-expiring ownership
=> std::unique_ptr<T> up4(std::move(up)); // EXPLICIT code allowed
=> std::unique_ptr<T> up4(up.release()); // EXPLICIT code allowed
위에서 ap3
조용히의 소유권을 "훔쳐" *ap
를 ap
설정 한 상태로 둡니다 nullptr
. 문제는 프로그래머가 안전을 고려하지 않고 너무 쉽게 발생할 수 있다는 것입니다.
For example, if a class
/struct
has a std::auto_ptr
member, then making a copy of an instance will release
the pointer from the instance being copied: that's weird and dangerously confusing semantics as usually copying something doesn't modify it. It's easy for the class/struct author to overlook the release of the pointer when reasoning about invariants and state, and consequently accidentally attempt to dereference smart-pointer while null, or just not still have expected access/ownership of the pointed-to data.
auto_ptr cannot be used in STL containers because it has a copy constructor that does not meet requirements of container CopyConstructible. unique_ptr does not implement a copy constructor, so containers use alternate methods. unique_ptr can be used in containers and is faster for std algorithms than shared_ptr.
#include <iostream>
#include <type_traits>
#include <vector>
#include <memory>
using namespace std;
int main() {
cout << boolalpha;
cout << "is_copy_constructible:" << endl;
cout << "auto_ptr: " << is_copy_constructible< auto_ptr<int> >::value << endl;
cout << "unique_ptr: " << is_copy_constructible< unique_ptr<int> >::value << endl;
cout << "shared_ptr: " << is_copy_constructible< shared_ptr<int> >::value << endl;
vector<int> i_v;
i_v.push_back(1);
cout << "i_v=" << i_v[0] << endl;
vector<int> i_v2=i_v;
cout << "i_v2=" << i_v2[0] << endl;
vector< unique_ptr<int> > u_v;
u_v.push_back(unique_ptr<int>(new int(2)));
cout << "u_v=" << *u_v[0] << endl;
//vector< unique_ptr<int> > u_v2=u_v; //will not compile, need is_copy_constructible == true
vector< unique_ptr<int> > u_v2 =std::move(u_v); // but can be moved
cout << "u_v2=" << *u_v2[0] << " length u_v: " <<u_v.size() << endl;
vector< shared_ptr<int> > s_v;
shared_ptr<int> s(new int(3));
s_v.push_back(s);
cout << "s_v=" << *s_v[0] << endl;
vector< shared_ptr<int> > s_v2=s_v;
cout << "s_v2=" << *s_v2[0] << endl;
vector< auto_ptr<int> > a_v; //USAGE ERROR
return 0;
}
>cxx test1.cpp -o test1
test1.cpp: In function âint main()â:
test1.cpp:33:11: warning: âauto_ptrâ is deprecated (declared at /apps/hermes/sw/gcc/gcc-4.8.5/include/c++/4.8.5/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
vector< auto_ptr<int> > a_v; //USAGE ERROR
^
>./test1
is_copy_constructible:
auto_ptr: false
unique_ptr: false
shared_ptr: true
i_v=1
i_v2=1
u_v=2
s_v=3
s_v2=3
참고URL : https://stackoverflow.com/questions/3697686/why-is-auto-ptr-being-deprecated
'Programing' 카테고리의 다른 글
go get으로 "인식 할 수없는 가져 오기 경로" (0) | 2020.09.19 |
---|---|
Visual Basic .NET에서 Char 리터럴을 어떻게 선언합니까? (0) | 2020.09.19 |
Javascript는 변수를 개체 이름으로 사용 (0) | 2020.09.19 |
Git : 'git reset'후 커밋 메시지를 재사용 / 보존하는 방법은 무엇입니까? (0) | 2020.09.19 |
rspec 3-클래스 메서드 스텁 (0) | 2020.09.19 |