it-swarm.com.de

C++ 11 Wenn ich shared_ptr lösche, sollte ich reset verwenden oder auf nullptr setzen?

Ich habe eine Frage zu den besten Vorgehensweisen für C++ 11. Soll ich beim Löschen eines shared_ptr die Funktion reset() ohne Parameter verwenden oder den shared_ptr auf nullptr setzen? Zum Beispiel:

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

Gibt es einen wirklichen Unterschied oder gibt es Vor- und Nachteile bei beiden Ansätzen?

50
user1930581

Gibt es einen wirklichen Unterschied oder gibt es bei beiden Ansätzen Vor- und Nachteile?

Die beiden Alternativen sind insofern absolut gleichwertig, als die zweite Form (foo = nullptr) in Bezug auf die erste definiert ist. In Absatz 20.7.1.2.3/8-10 des C++ 11-Standards heißt es:

 unique_ptr& operator=(nullptr_t) noexcept;

8 Effekte : reset().

9 Nachbedingung : get() == nullptr

10 Gibt zurück: *this.

Deshalb wählen Sie einfach die aus, die die Absicht für Sie am deutlichsten macht. Persönlich bevorzuge ich:

foo = nullptr;

Weil dadurch klarer wird, dass der Zeiger null sein soll. Versuchen Sie jedoch generell, die Situationen zu minimieren, in denen Sie einen Smart Pointer explizit zurücksetzen müssen.


Anstatt new zu verwenden:

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

Erwägen Sie nach Möglichkeit die Verwendung von std::make_shared():

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

Ich würde reset() vorziehen, da dies die Absicht signalisiert. Versuchen Sie jedoch, Ihren Code so zu schreiben, dass Sie nicht explizit einen shared_ptr<> löschen müssen, d. H. Sicherstellen, dass ein shared_ptr<> den Gültigkeitsbereich verlässt, wenn Sie ihn andernfalls löschen würden.

12
Walter

Sie unterscheiden sich ein wenig, wenn Sie https://godbolt.org/ verwenden, um zu überprüfen
mit gcc (7.2)
foo.reset(); Generiert Assembly-Code 

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

foo = nullptr; wird jedoch generiert

  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()

Es erstellt einen gemeinsamen Zeiger mit nullptr, weist der Variablen das neu erstellte Objekt zu und ruft destructor als destory-String auf.

Da weiß ich nicht, wie ich überprüfen kann, was in der Funktion reset () passiert ist. Kann nicht sehen was schneller ist.

0
r0ng