배열에 shared_ptr : 사용해야합니까?
에 관한 작은 쿼리 shared_ptr
입니다.
shared_ptr
배열을 가리키는 것을 사용하는 것이 좋습니다 ? 예를 들어
shared_ptr<int> sp(new int[10]);
그렇지 않다면 왜 안됩니까? 내가 이미 알고있는 한 가지 이유는를 늘리거나 줄일 수 없기 때문 shared_ptr
입니다. 따라서 배열에 대한 일반적인 포인터처럼 사용할 수 없습니다.
함께 C ++ 17 , shared_ptr
동적으로 할당 된 어레이를 관리하기 위해 사용될 수있다. shared_ptr
이 경우 템플릿 인수해야 T[N]
하거나 T[]
. 그래서 당신은 쓸 수 있습니다
shared_ptr<int[]> sp(new int[10]);
n4659부터 [util.smartptr.shared.const]
template<class Y> explicit shared_ptr(Y* p);
요구 사항 :
Y
완전한 유형이어야한다. , 표현식 이 배열 유형일 때 또는 배열 유형이 아닌delete[] p
경우 표현식 은 올바르게 정의 된 동작을 가지며 예외를 발생시키지 않습니다. ... 설명 : 때 어레이 타입 표현이없는 한,이 생성자 과부하 해상도에 참여하지 않아야한다 잘 형성되고 하나 이며 하고 로 변환 가능한 , 또는 인 및 으로 변환이다 . ...T
delete p
T
T
delete[] p
T
U[N]
Y(*)[N]
T*
T
U[]
Y(*)[]
T*
이를 지원하기 위해 멤버 유형 element_type
이 이제
using element_type = remove_extent_t<T>;
배열 요소는 다음을 사용하여 액세스 할 수 있습니다. operator[]
element_type& operator[](ptrdiff_t i) const;
필요합니다 :
get() != 0 && i >= 0
. 경우T
이다U[N]
,i < N
. ...
설명 : 경우T
배열 형이 아니라,이 멤버 함수가 선언되는지 여부를 지정한다. 선언 된 경우 함수의 선언 (정의 일 필요는 없지만)이 올바르게 형성되는 것을 제외하고는 반환 유형이 무엇인지 지정되지 않습니다.
앞서 C ++ 17 , shared_ptr
수 없습니다 동적으로 할당 된 배열을 관리 할 수. 기본적으로 더 이상 참조가 남아 있지 않으면 관리 대상 객체를 shared_ptr
호출 delete
합니다. 사용 할당 할 때, new[]
당신은 호출 할 필요가 delete[]
아닌 delete
, 리소스를 확보 할 수 있습니다.
shared_ptr
어레이와 함께 올바르게 사용하려면 사용자 정의 삭제기를 제공해야합니다.
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
다음과 같이 shared_ptr을 작성하십시오.
std::shared_ptr<int> sp(new int[10], array_deleter<int>());
이제 관리 대상 객체를 삭제할 때 shared_ptr
올바르게 호출 delete[]
합니다.
위의 맞춤 삭제 프로그램은 다음으로 대체 될 수 있습니다.
std::default_delete
어레이 타입 부분 특수화std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
람다 표현
std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
또한 실제로 관리 대상 개체에 대한 공유 권한이 필요하지 않은 한, unique_ptr
배열 유형에 대한 부분 전문화 기능이 있기 때문에이 작업에 더 적합합니다.
std::unique_ptr<int[]> up(new int[10]); // this will correctly call delete[]
라이브러리 기초를위한 C ++ 확장에 의해 도입 된 변경 사항
위에 열거 된 것들에 대한 또 다른 C ++ 17 이전 대안은 Library Fundamentals Technical Specification에 의해 제공되었으며 , 이는 shared_ptr
객체 배열을 소유 한 경우에 대해 즉시 사용할 수 있도록 향상되었습니다. shared_ptr
이 TS에 예정된 변경 사항 의 현재 초안은 N4082 에서 찾을 수 있습니다 . 이러한 변경 사항은 std::experimental
네임 스페이스 를 통해 액세스 할 수 있으며 <experimental/memory>
헤더에 포함됩니다 . shared_ptr
배열 을 지원 하기 위해 관련된 몇 가지 변경 사항 은 다음과 같습니다.
— 멤버 유형의 정의가 element_type
변경됨
typedef T element_type;typedef typename remove_extent<T>::type element_type;
— 회원 operator[]
추가 중
element_type& operator[](ptrdiff_t i) const noexcept;
— Unlike the unique_ptr
partial specialization for arrays, both shared_ptr<T[]>
and shared_ptr<T[N]>
will be valid and both will result in delete[]
being called on the managed array of objects.
template<class Y> explicit shared_ptr(Y* p);
Requires:
Y
shall be a complete type. The expressiondelete[] p
, whenT
is an array type, ordelete p
, whenT
is not an array type, shall be well-formed, shall have well defined behavior, and shall not throw exceptions. WhenT
isU[N]
,Y(*)[N]
shall be convertible toT*
; whenT
isU[]
,Y(*)[]
shall be convertible toT*
; otherwise,Y*
shall be convertible toT*
.
A possibly easier alternative that you might be able to use is shared_ptr<vector<int>>
.
참고URL : https://stackoverflow.com/questions/13061979/shared-ptr-to-an-array-should-it-be-used
'IT' 카테고리의 다른 글
왜 필드 셋 태그가 필요합니까? (0) | 2020.06.07 |
---|---|
C ++ 연산자의 암시 적 유형 변환 규칙 (0) | 2020.06.07 |
“npm 구성 세트 레지스트리 https://registry.npmjs.org/”가 Windows bat 파일에서 작동하지 않습니다 (0) | 2020.06.06 |
왜 Console.Writeline, Console.Write가 Visual Studio Express에서 작동하지 않습니까? (0) | 2020.06.06 |
약 2GB의 텍스트 파일을 어떻게 읽습니까? (0) | 2020.06.06 |