2013-06-03 2 views
29

나는 std::unique_ptr가 어떻게 작동 하는지를 알아 내려고, 그 결과로 this 문서를 발견했다.std :: unique_ptr을 선언하는 방법과 그 사용법은 무엇입니까?

#include <utility> //declarations of unique_ptr 
using std::unique_ptr; 
// default construction 
unique_ptr<int> up; //creates an empty object 
// initialize with an argument 
unique_ptr<int> uptr (new int(3)); 
double *pd= new double; 
unique_ptr<double> uptr2 (pd); 
// overloaded * and -> 
*uptr2 = 23.5; 
unique_ptr<std::string> ups (new std::string("hello")); 
int len=ups->size(); 

무엇을 나에게 혼란 것은이 줄

unique_ptr<int> uptr (new int(3)); 

우리는

unique_ptr<double> uptr2 (pd); 
여기 (괄호 사이) 인수로 정수를 사용하고 있다는 점이다 : 저자는 다음의 예에서 시작

포인터를 인수로 사용했습니다. 어떤 차이가 있습니까?

나에게도 명확하지 않은 점은이 방법으로 선언 된 포인터가 "정상적인"방법으로 선언 된 포인터와 다른 점입니다.

+4

'new int (3)'은 새로운'double'에 대한 포인터 인'pd'와 마찬가지로 새로운'int'에 대한 포인터를 반환합니다. –

답변

3

범위를 벗어나면 고유 포인터가 파괴 될 수 있습니다. 경우 http://en.cppreference.com/w/cpp/memory/unique_ptr

: 당신이 범위를 벗어나 갈 때

unique_ptr<double> uptr2 (pd); 

PD가 파괴됩니다. 이것은 자동 삭제로 메모리 관리를 용이하게합니다. 그 원시 포인터 여기

35

unique_ptr<T> 생성자 유형 T의 객체에 대한 원시 포인터를 받아들이는 임의의 변수에 할당되지 않는 것을 제외하고

다음 unique_ptr<int> uptr (new int(3));의 경우 (따라서, 그것은 T* 허용) 다르지 않다.

첫 번째 예

:

unique_ptr<double> uptr2 (pd); 

포인터는 pd 변수에 저장된다

unique_ptr<int> uptr (new int(3)); 

포인터 번째 예에서 동안, new 식의 결과이다. 개념적으로

는 아무것도 (당신이 원시 포인터에서 unique_ptr를 구축하는) 변경,하지만 두 번째 방법은 예를 들어, 할, 당신을 허용 것이기 때문에, 잠재적으로 더 위험하다 : 따라서 필요

unique_ptr<double> uptr2 (pd); 
// ... 
unique_ptr<double> uptr3 (pd); 

두 개의 동일한 객체를 효과적으로 캡슐화하는 고유 포인터 (따라서 고유 한 포인터의 의미를 위반 함).

가능한 경우 고유 포인터를 만드는 첫 번째 형식이 더 좋은 이유입니다. C++ 14에서는 다음과 같은 작업을 수행 할 수 있습니다.

unique_ptr<int> p = make_unique<int>(42); 

더 명확하고 안전합니다.이제 당신의 의심에 관한 :

What is also not clear to me, is how pointers, declared in this way will be different from the pointers declared in a "normal" way.

스마트 포인터가 개체의 소유권을 모델링, 자동으로 해당 개체에 대한 마지막 (스마트, 소유) 포인터가 범위를 벗어날 때 뾰족한 물체를 파괴 돌봐로되어있다.

동적으로 할당 된 객체에 대해 delete을 수행 한 것을 기억할 필요가 없습니다. 스마트 포인터의 소멸자가이를 수행 할 것이며, 객체에 대한 (매달 리지 않은) 포인터를 역 참조하지 않을지 걱정하지 않아도됩니다. 이미 파괴되었습니다

{ 
    unique_ptr<int> p = make_unique<int>(42); 
    // Going out of scope... 
} 
// I did not leak my integer here! The destructor of unique_ptr called delete 

지금 unique_ptr는 만 이 뾰족한 물체로 (소유) 포인터를 하나의 프로그램에서 언제든지 존재한다 것을 의미 모델 고유의 소유권을 스마트 포인터 - 그 이유는 unique_ptr있어 복사 할 수 없습니다.

암시 적 계약을 위반하지 않는 방식으로 스마트 포인터를 사용하는 경우 준수해야하는 스마트 포인터를 사용하는 경우 메모리 누출이 없음을 보장하고 개체에 대한 적절한 소유권 정책이 강제. 원시 포인터는이 보증을 제공하지 않습니다.

+2

안녕하세요, 저는 모델 객체 소유권, 코드의 '정수 누출'또는 '객체 소유권 정책 시행'에 대해 아무 것도 이해할 수 없었습니다. 이 개념을 배우기 위해 주제/자료를 제안 해주십시오. –

+0

'unique_ptr'을 사용하지 않고서도 오류가 발생하지 않습니다 :'text ">"는 예상치 못한 결과입니다. '#include '과'#include '을 가지고 있는데도이 토큰이 템플릿 인자 목록 종결 자로 의도되었지만 그 이름은 템플릿이 아닌 것으로 알 수 있습니다. ' 어떤 충고? – Anonymous

2

unique_ptr에 대한 할당 개념에는 차이점이 없습니다. 당신은, 당신은해야합니다에 ( 키워드 또는 malloc에 ​​ 새로운 사용) 힙 공간의 정수를 만들 경우

int* intPtr = new int(3); 
unique_ptr<int> uptr (intPtr); 

unique_ptr<int> uptr (new int(3)); 


how pointers, declared in this way will be different from the pointers declared in a "normal" way.

유사하다 그 기억을 스스로 지우십시오 (을 사용하여 삭제 또는 무료). 그것을 사용하여 수행 될 때 , heapInt을 삭제하려면 아래 코드에서

, 여기

int* heapInt = new int(5);//initialize int in heap memory 
. 
.//use heapInt 
. 
delete heapInt; 

, 당신은해야합니다. 삭제되지 않으면 메모리 누수가 발생합니다.
이러한 메모리 누수를 피하기 위해 unique_ptr이 사용됩니다. unique_ptr은 범위를 벗어날 때 heapInt가 차지하는 공간을 자동으로 삭제합니다.