IT

배열에 shared_ptr : 사용해야합니까?

lottoking 2020. 6. 7. 10:07
반응형

배열에 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경우 표현식 은 올바르게 정의 된 동작을 가지며 예외를 발생시키지 않습니다. ... 설명 :어레이 타입 표현이없는 한,이 생성자 과부하 해상도에 참여하지 않아야한다 잘 형성되고 하나 이며 하고 로 변환 가능한 , 또는 으로 변환이다 . ...Tdelete pT

Tdelete[] pTU[N]Y(*)[N]T*TU[]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 expression delete[] p, when T is an array type, or delete p, when T is not an array type, shall be well-formed, shall have well defined behavior, and shall not throw exceptions. When T is U[N], Y(*)[N] shall be convertible to T*; when T is U[], Y(*)[] shall be convertible to T*; otherwise, Y* shall be convertible to T*.


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

반응형