std::unique_ptr<T,Deleter>:: unique_ptr
|
기본 템플릿의 멤버들, unique_ptr<T>
|
||
|
constexpr
unique_ptr
(
)
noexcept
;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ; |
(1) | |
|
explicit
unique_ptr
(
pointer p
)
noexcept
;
|
(2) | (C++23부터 constexpr) |
|
unique_ptr
(
pointer p,
/* 아래 참조 */
d1
)
noexcept
;
|
(3) | (C++23부터 constexpr) |
|
unique_ptr
(
pointer p,
/* 아래 참조 */
d2
)
noexcept
;
|
(4) | (C++23부터 constexpr) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (C++23부터 constexpr) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (C++23부터 constexpr) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
|
template
<
class
U
>
unique_ptr ( std:: auto_ptr < U > && u ) noexcept ; |
(8) | (C++17에서 제거됨) |
|
배열에 대한 특수화 멤버, unique_ptr<T[]>
|
||
|
constexpr
unique_ptr
(
)
noexcept
;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ; |
(1) | |
|
template
<
class
U
>
explicit unique_ptr ( U p ) noexcept ; |
(2) | (C++23부터 constexpr) |
|
template
<
class
U
>
unique_ptr ( U p, /* 아래 참조 */ d1 ) noexcept ; |
(3) | (C++23부터 constexpr) |
|
template
<
class
U
>
unique_ptr ( U p, /* 아래 참조 */ d2 ) noexcept ; |
(4) | (C++23부터 constexpr) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (C++23부터 constexpr) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (C++23부터 constexpr) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
std::unique_ptr
를 생성합니다. 저장된 포인터와 저장된 삭제자를 값 초기화합니다.
Deleter
가
DefaultConstructible
이며 생성 과정에서 예외를 발생시키지 않아야 합니다. 이 오버로드들은
std::
is_default_constructible
<
Deleter
>
::
value
가
true
이고
Deleter
가 포인터 타입이 아닌 경우에만 오버로드 해결에 참여합니다.
std::unique_ptr
를 생성하며, 이는
p
를 소유합니다. 저장된 포인터를
p
로 초기화하고 저장된 삭제자를 값 초기화합니다.
Deleter
가
DefaultConstructible
요구 사항을 만족해야 하며, 생성 과정에서 예외가 발생하지 않아야 합니다. 이 오버로드는
std::
is_default_constructible
<
Deleter
>
::
value
가
true
이고
Deleter
가 포인터 타입이 아닌 경우에만 오버로드 해결에 참여합니다.
|
이 생성자는 클래스 템플릿 인수 추론 에 의해 선택되지 않습니다. |
(C++17부터) |
std::unique_ptr
객체를 생성하며, 이 객체는
p
를 소유합니다. 저장된 포인터를
p
로 초기화하고, 삭제자
D
를 아래와 같이 초기화합니다(
D
가 참조 타입인지 여부에 따라 다름).
D
가 비-참조 타입
A
인 경우, 시그니처는 다음과 같습니다:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) |
(
Deleter
가 nothrow-
CopyConstructible
임을 요구함)
|
|
unique_ptr
(
pointer p, A
&&
d
)
noexcept
;
|
(2) |
(
Deleter
가 nothrow-
MoveConstructible
임을 요구함)
|
D
가 lvalue-reference 타입
A
&
인 경우, 시그니처는 다음과 같습니다:
|
unique_ptr
(
pointer p, A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p, A
&&
d
)
=
delete
;
|
(2) | |
D
가 lvalue-reference 타입
const
A
&
인 경우, 시그니처는 다음과 같습니다:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p,
const
A
&&
d
)
=
delete
;
|
(2) | |
|
이 두 생성자는 클래스 템플릿 인수 추론 에 의해 선택되지 않습니다. |
(C++17부터) |
-
U가pointer와 동일한 타입인 경우, 또는 -
U가 std::nullptr_t 인 경우, 또는 -
pointer가element_type*와 동일한 타입이고U가V*와 같은 포인터 타입이며,V(*)[]가element_type(*)[]로 암시적으로 변환 가능한 경우.
unique_ptr
의 소유권을
u
에서
*
this
로 이전하여 생성하며,
u
에는 널 포인터를 저장합니다. 이 생성자는
std::
is_move_constructible
<
Deleter
>
::
value
가
true
인 경우에만 오버로드 해결에 참여합니다.
Deleter
가 참조 타입이 아닌 경우, nothrow-
MoveConstructible
을 요구합니다 (
Deleter
가 참조인 경우, 이동 생성 후
get_deleter()
와
u.get_deleter()
는 동일한 값을 참조합니다).
unique_ptr
를 생성하며, 소유권을
u
에서
*
this
로 이전합니다. 여기서
u
는 지정된 삭제자(
E
)로 생성됩니다. 이 동작은
E
가 참조 타입인지 여부에 따라 다음과 같이 달라집니다:
E
가 참조 타입인 경우, 이 삭제자는
u
의 삭제자로부터 복사 생성됩니다 (이 생성 과정이 예외를 발생시키지 않아야 함).
E
가 비-참조 타입인 경우, 이 deleter는
u
의 deleter로부터 이동 생성됩니다 (이 생성 작업이 예외를 발생시키지 않아야 함).
pointer
로 변환 가능합니다,
Deleter
가 참조 타입이고
E
가
Deleter
와 동일한 타입이거나,
Deleter
가 참조 타입이 아니고
E
가
Deleter
로 암시적으로 변환 가능한 경우.
-
U가 배열 타입인 경우, -
pointer가element_type*와 동일한 타입인 경우, - unique_ptr < U,E > :: pointer 가 unique_ptr < U,E > :: element_type * 와 동일한 타입인 경우,
-
unique_ptr
<
U,E
>
::
element_type
(
*
)
[
]
가
element_type(*)[]로 변환 가능한 경우, -
Deleter가 참조 타입이고E가Deleter와 동일한 타입이거나, 또는Deleter가 참조 타입이 아니고E가Deleter로 암시적으로 변환 가능한 경우.
unique_ptr
을 생성합니다. 이 생성자는
U*
가
T*
로 암시적으로 변환 가능하고
Deleter
가
std::
default_delete
<
T
>
와 동일한 타입일 때만 오버로드 해결에 참여합니다.
목차 |
매개변수
| p | - | 관리할 객체에 대한 포인터 |
| d1, d2 | - | 객체를 파괴하는 데 사용할 삭제자 |
| u | - | 소유권을 획득할 다른 스마트 포인터 |
참고 사항
|
new와 함께 (2) 오버로드를 사용하는 대신, std::make_unique<T> 를 사용하는 것이 종종 더 나은 방법입니다. |
(since C++14) |
std:: unique_ptr < Derived > 는 오버로드 (6) 를 통해 std:: unique_ptr < Base > 로 암시적으로 변환 가능합니다 (관리되는 포인터와 std::default_delete 모두 암시적으로 변환 가능하기 때문입니다).
기본 생성자가 constexpr 이므로, 정적 unique_ptr들은 정적 비지역 변수 초기화 과정에서 동적 비지역 초기화가 시작되기 전에 초기화됩니다. 이로 인어 어떤 정적 객체의 생성자에서도 unique_ptr을 안전하게 사용할 수 있습니다.
|
배열 형태와 비배열 형태의 new 에서 얻은 포인터를 구분할 수 없기 때문에 포인터 타입으로부터 클래스 템플릿 인수 추론 이 존재하지 않습니다. |
(C++17부터) |
예제
#include <iostream> #include <memory> struct Foo // 관리할 객체 { Foo() { std::cout << "Foo 생성자\n"; } Foo(const Foo&) { std::cout << "Foo 복사 생성자\n"; } Foo(Foo&&) { std::cout << "Foo 이동 생성자\n"; } ~Foo() { std::cout << "~Foo 소멸자\n"; } }; struct D // deleter { D() {}; D(const D&) { std::cout << "D 복사 생성자\n"; } D(D&) { std::cout << "D 비상수 복사 생성자\n"; } D(D&&) { std::cout << "D 이동 생성자 \n"; } void operator()(Foo* p) const { std::cout << "D가 Foo를 삭제 중입니다\n"; delete p; }; }; int main() { std::cout << "예제 생성자(1)...\n"; std::unique_ptr<Foo> up1; // up1이 비어 있음 std::unique_ptr<Foo> up1b(nullptr); // up1b is empty std::cout << "예시 생성자(2)...\n"; { std::unique_ptr<Foo> up2(new Foo); //up2가 Foo를 소유함 } // Foo 삭제됨 std::cout << "예시 생성자(3)...\n"; D d; { // deleter 타입은 참조가 아님 std::unique_ptr<Foo, D> up3(new Foo, d); // deleter 복사됨 } { // deleter 타입은 참조형입니다 std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b는 d에 대한 참조를 보유합니다 } std::cout << "예제 생성자(4)...\n"; { // deleter는 참조가 아님 std::unique_ptr<Foo, D> up4(new Foo, D()); // deleter moved } std::cout << "Example constructor(5)...\n"; { std::unique_ptr<Foo> up5a(new Foo); std::unique_ptr<Foo> up5b(std::move(up5a)); // 소유권 이전 } std::cout << "예시 생성자(6)...\n"; { std::unique_ptr<Foo, D> up6a(new Foo, d); // D가 복사됨 std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D가 이동됨 std::unique_ptr<Foo, D&> up6c(new Foo, d); // D는 참조입니다 std::unique_ptr<Foo, D> up6d(std::move(up6c)); // D가 복사됨 } #if (__cplusplus < 201703L) std::cout << "예제 생성자(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::move(up7a)); // 소유권 이전 } #endif std::cout << "예시 배열 생성자...\n"; { std::unique_ptr<Foo[]> up(new Foo[3]); } // 세 개의 Foo 객체 삭제됨 }
출력:
예시 생성자(1)... 예시 생성자(2)... Foo ctor ~Foo dtor 예시 생성자(3)... Foo ctor D 복사 생성자 D가 Foo를 삭제 중 ~Foo dtor Foo ctor D가 Foo를 삭제 중 ~Foo dtor 예시 생성자(4)... Foo ctor D 이동 생성자 D가 Foo를 삭제 중 ~Foo dtor 예시 생성자(5)... Foo ctor ~Foo dtor 예시 생성자(6)... Foo ctor D 복사 생성자 D 이동 생성자 Foo ctor D 비상수 복사 생성자 D가 Foo를 삭제 중 ~Foo dtor D가 Foo를 삭제 중 ~Foo dtor 예시 생성자(7)... Foo ctor ~Foo dtor 예시 배열 생성자... Foo ctor Foo ctor Foo ctor ~Foo dtor ~Foo dtor ~Foo dtor
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2118 | C++11 |
unique_ptr<T[]>
의 생성자들이 한정 변환(qualification conversions)을 거부했습니다.
|
수용. |
| LWG 2520 | C++11 |
unique_ptr<T[]>
가 실수로
nullptr_t
로부터 생성 불가능하게 되었습니다.
|
생성 가능하게 변경. |
| LWG 2801 | C++11 | 기본 생성자가 제약되지 않았습니다. | 제약됨. |
| LWG 2899 | C++11 | 이동 생성자가 제약되지 않았습니다. | 제약됨. |
| LWG 2905 | C++11 | 포인터와 삭제자로부터의 생성자에 대한 제약이 잘못되었습니다. | 수정됨. |
| LWG 2944 | C++11 | 일부 사전 조건들이 LWG 2905에 의해 실수로 제거되었습니다. | 복원됨. |