Program Tip

C ++ 11 shared_ptr을 지울 때 reset을 사용하거나 nullptr로 설정해야합니까?

programtip 2020. 12. 12. 12:17
반응형

C ++ 11 shared_ptr을 지울 때 reset을 사용하거나 nullptr로 설정해야합니까?


C ++ 11 모범 사례에 대한 질문이 있습니다. shared_ptr을 클리어 할 때, 나는 사용해야 reset()어떤 매개 변수 기능을, 또는 내가 설정해야 shared_ptrnullptr? 예를 들면 :

std::shared_ptr<std::string> foo(new std::string("foo"));
foo.reset();
foo = nullptr;

실제 차이가 있습니까, 아니면 두 접근 방식 모두에 장단점이 있습니까?


실제 차이가 있습니까, 아니면 두 접근 방식 모두에 장단점이 있습니까?

두 번째 형식 ( foo = nullptr)이 첫 번째 형식 으로 정의 된다는 점에서 두 가지 대안은 절대적으로 동일 합니다. C ++ 11 표준의 단락 20.7.1.2.3 / 8-10에 따라 :

 unique_ptr& operator=(nullptr_t) noexcept;

8 효과 :reset() .

9 사후 조건 :get() == nullptr

10 반환 : *this.

따라서 의도를 가장 명확하게하는 것을 선택하십시오 . 개인적으로 다음을 선호합니다.

foo = nullptr;

포인터가 null이되기를 원한다는 것이 더 분명해지기 때문입니다. 그러나 일반적인 조언 으로 스마트 포인터 명시 적으로 재설정 해야하는 상황을 최소화하십시오 .


게다가 사용하는 것보다 new:

std::shared_ptr<std::string> foo(new std::string("foo"));

std::make_shared()가능한 경우 사용을 고려하십시오 .

auto foo = std::make_shared<std::string>("foo");

나는 reset()그것이 의도를 나타내는 것을 선호합니다 . 그러나 명시 적으로 a를 지울 필요가 없도록 코드를 작성하십시오 shared_ptr<>. 즉, shared_ptr<>다른 방법으로 지울 때 a 가 범위를 벗어나도록하십시오.


당신이 사용하는 경우 그들은 조금 다른이 https://godbolt.org/을 확인하기 위해
GCC (7.2)를 사용하여
foo.reset();어셈블리 코드를 생성

  lea rax, [rbp-32]
  mov rdi, rax
  call std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::reset()

그러나 foo = nullptr;생성

  lea rax, [rbp-16]
  mov esi, 0
  mov rdi, rax
  call std::shared_ptr<int>::shared_ptr(decltype(nullptr))
  lea rdx, [rbp-16]
  lea rax, [rbp-32]
  mov rsi, rdx
  mov rdi, rax
  call std::shared_ptr<int>::operator=(std::shared_ptr<int>&&)
  lea rax, [rbp-16]
  mov rdi, rax
  call std::shared_ptr<int>::~shared_ptr()

nullptr로 공유 포인터를 생성하고 새로 생성 된 객체를 변수에 할당하고 destory string에 destructor를 호출합니다.

reset () 함수에서 무슨 일이 일어 났는지 확인하는 방법을 모르기 때문에. 어느 것이 더 빠른지 알 수 없습니다.


일반적으로 스마트 포인터는 스스로 처리 할 수 ​​있습니다. 그러나 해결책이 필요하다면 reset()제 생각에는 최선의 방법입니다.

참고 URL : https://stackoverflow.com/questions/16151550/c11-when-clearing-shared-ptr-should-i-use-reset-or-set-to-nullptr

반응형