Warum ist es falsch, std::auto_ptr mit Standardcontainern zu verwenden?

Lesezeit: 6 Minuten

Warum ist es falsch stdauto ptr mit Standardcontainern zu verwenden
Uhall

Warum ist es falsch zu verwenden std::auto_ptr<> mit Standardcontainern?

  • Definitiv ein +1 dafür, weil ich gesehen habe, dass so viele Leute das falsch verstanden haben. Es ist eine großartige Frage.

    – Zweikats

    7. November 2008 um 20:42 Uhr

  • Bitte lesen Sie auch den entsprechenden Artikel. Diese Frage wird hier von der anderen Seite betrachtet. Kann hilfreich sein, um mehr über auto_ptr und STL-Container zu erfahren. stackoverflow.com/questions/8630552/…

    – Nickolay

    29. Dezember 2011 um 11:59 Uhr


  • Häufig gestellte Fragen zu C++: Kann ich einen Container mit intelligenten Zeigern auf meine Objekte haben?

    – Amro

    18. Mai 2012 um 1:44 Uhr

  • move semantisch u unique_ptr wurden entwickelt, um die damit verbundenen Probleme zu vermeiden auto_ptr. In C++ 03 war die Sprache nicht mächtig genug, um eine Klasse wie zu schreiben auto_ptr die sich in allen Szenarien korrekt und sicher verhalten, da der Compiler und die Sprache nicht in der Lage waren, l- und r-Werte zu unterscheiden, sodass einige “Hacks” verwendet wurden, um die meiste Zeit das gewünschte Verhalten zu erzielen.

    – Phil1970

    12. Mai 2017 um 3:22 Uhr

  • Schöner Artikel: STL-Container und Auto_ptrs – Warum sie nicht mischen quantstart.com/articles/…

    – alfC

    8. Juni 2020 um 9:08 Uhr


Der C++-Standard besagt, dass ein STL-Element „kopierbar“ und „zuweisbar“ sein muss. Das heißt, ein Element muss zuweisbar oder kopierbar sein und die beiden Elemente müssen logisch unabhängig sein. std::auto_ptr erfüllt diese Anforderung nicht.

Nehmen Sie zum Beispiel diesen Code:

class X
{
};

std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);

std::auto_ptr<X> pX = vecX[0];  // vecX[0] is assigned NULL.

Um diese Einschränkung zu überwinden, sollten Sie die verwenden std::unique_ptr, std::shared_ptr oder std::weak_ptr Smart Pointer oder die Boost-Äquivalente, wenn Sie C++11 nicht haben. Hier ist die Dokumentation der Boost-Bibliothek für diese intelligenten Zeiger.

  • Sie sollten auch die Boost-Zeiger-Container in Betracht ziehen, wenn Sie kein gemeinsames Eigentum benötigen.

    – ich22

    10. September 2009 um 16:34 Uhr

  • unique_ptr verbietet auch das Kopieren, sodass bestimmte STL-Operationen nicht korrekt funktionieren, es sei denn, sie können ihre Bewegungssemantik verwenden.

    – Mike Weller

    1. Juli 2013 um 9:54 Uhr

  • “Um diese Einschränkung zu überwinden, sollten Sie die verwenden std::unique_ptr“: Diese Klassenvorlage kann nur aufgrund der Bewegungssemantik existieren (ihre Spezifikation erfordert Rvalue-Referenzen), daher ist grundsätzlich C++11 erforderlich. Der C++11-Standard sagt jedoch (und damit zusammenhängend) nicht mehr, dass ein STL-Elementtyp sein muss „kopierkonstruierbar“ und „zuweisbar“, es reicht aus, bewegungskonstruierbar und bewegungszuweisbar zu sein unique_ptr Instanzen sind nur bewegungskonstruierbar und bewegungszuweisbar. Aber so sind auto_ptr Fälle! Infolgedessen können Sie in C++ 11 mit auto_ptr was du damit machen kannst unique_ptr.

    – Marc van Leeuwen

    27. August 2014 um 9:26 Uhr


  • @MarcvanLeeuwen, es sei denn, Sie reset und release wie benötigt

    – Ratschenfreak

    3. September 2014 um 7:47 Uhr

  • @ratchetfreak: Hmm, verstehe ich nicht. Was? “Außer du reset und release“Ich sehe nicht, wie das auf irgendetwas in meinem Kommentar zutrifft. Beachten Sie, dass beides gilt auto_ptr und unique_ptr haben diese beiden Methoden, und sie tun in beiden Fällen dasselbe.

    – Marc van Leeuwen

    3. September 2014 um 9:05 Uhr

1646955611 640 Warum ist es falsch stdauto ptr mit Standardcontainern zu verwenden
Frank Krüger

Die Semantik kopieren von auto_ptr sind mit den Behältern nicht kompatibel.

Insbesondere das Kopieren eines auto_ptr zu einem anderen erstellt nicht zwei gleiche Objekte, da eines seinen Besitz des Zeigers verloren hat.

Genauer gesagt, das Kopieren einer auto_ptr bewirkt, dass eine der Kopien den Zeiger loslässt. Was davon im Behälter verbleibt, ist nicht definiert. Daher können Sie zufällig den Zugriff auf Zeiger verlieren, wenn Sie speichern auto_ptrs in den Behältern.

Zwei super exzellente Artikel zum Thema:

  • Weil ich denke, dass er sich in den dazwischenliegenden fast zwei Jahren wahrscheinlich mit dem vorliegenden Problem befasst hat.

    – Hündchen

    25. Juni 2010 um 20:31 Uhr

  • @DeadMG: Ja, du hast Recht. Aber das war nicht meine Absicht. Falls jemand irgendwann mal in diesen Thread kommt und sich informieren will auto_ptr und so, diese Links werden hilfreich sein, da bin ich mir sicher.

    – Laser

    25. Juni 2010 um 20:44 Uhr

  • Es gibt viele Duplikate, die neuer sind.

    – Hündchen

    25. Juni 2010 um 21:23 Uhr

  • @DeadMG: Diese Frage wurde nicht als Duplikat geschlossen und kann daher erweitert werden. Lazer sagte, was hier vorher nicht gesagt wurde. Ich schätze, er kam zufällig vorbei.

    – Sebastian Mach

    18. November 2011 um 16:21 Uhr

  • Die Erläuterungen im zweiten Link, die das Problem nach Aufruf analysieren sort()sind klarer als alle Antworten hier.

    – Chaos

    1. Mai 2020 um 19:35 Uhr

1641662428 385 Unit Tests eines Java Servlets
Garth Gilmour

Die STL-Container müssen in der Lage sein, die darin gespeicherten Artikel zu kopieren, und sind so konzipiert, dass das Original und die Kopie gleichwertig sind. Auto-Pointer-Objekte haben einen ganz anderen Vertrag, wobei das Kopieren einen Eigentumsübergang bewirkt. Das bedeutet, dass Container von auto_ptr je nach Verwendung ein seltsames Verhalten aufweisen.

Es gibt eine detaillierte Beschreibung dessen, was schief gehen kann, in Punkt 8 von Effektivem STL (Scott Meyers) und auch eine nicht so detaillierte Beschreibung in Punkt 13 von Effektivem C++ (Scott Meyers).

STL-Container speichern Kopien enthaltener Elemente. Wenn ein auto_ptr kopiert wird, setzt er den alten ptr auf null. Viele Containermethoden werden durch dieses Verhalten beschädigt.

  • Aber wenn Sie unique_ptr verwenden, erhalten Sie so ziemlich dasselbe, da nur ein unique_ptr das Eigentum an dem Objekt haben kann?

    – Tracer

    11. Juli 2014 um 6:56 Uhr

  • @ Tracer unique_ptr Wie jedes richtige C++ 11-Objekt kann das Eigentum an seiner Ressource nur übertragen werden, wenn es verschoben oder zugewiesen wird, wodurch sichergestellt wird, dass der Programmierer absichtlich eine übergeben muss std::move(sourceObject) oder eine vorübergehende, anstatt eine zu übergeben Wert und unintuitiv / unvorhersehbar durch die Kopierzuweisung mutiert … was, wie hier ausführlich betont wird, ein Kernproblem von war auto_ptr.

    – Unterstrich_d

    23. Februar 2016 um 0:15 Uhr


C++03-Standard (ISO-IEC 14882-2003) heißt es in Ziffer 20.4.5 Absatz 3:

[…]
[Note: […]

auto_ptr erfüllt nicht die CopyConstructible- und Assignable-Anforderungen für Containerelemente der Standardbibliothek, und daher führt die Instanziierung eines Standardbibliothekscontainers mit einem auto_ptr zu undefiniertem Verhalten. — Endnote]

C++11-Standard (ISO-IEC 14882-2011) heißt es in Anhang D.10.1 Absatz 3:

[…]
Notiz: […] Instanzen von auto_ptr erfüllen die Anforderungen von MoveConstructible und MoveAssignable, aber nicht die Anforderungen von CopyConstructible und CopyAssignable. — Endnote]

C++14-Standard (ISO-IEC 14882-2014) heißt es in Anhang C.4.2 Anhang D: Kompatibilitätsmerkmale:

ÄndernHinweis: Die Klassenvorlagen auto_ptr, unary_function und binary_function, die Funktionsvorlagen random_shuffle und die Funktionsvorlagen (und ihre Rückgabetypen) ptr_fun, mem_fun, mem_fun_ref, bind1st und bind2nd sind nicht definiert.
Begründung: Durch neue Funktionen ersetzt.
Auswirkung auf das ursprüngliche Merkmal: Gültiger C ++ 2014-Code, der diese Klassenvorlagen und Funktionsvorlagen verwendet, kann möglicherweise nicht in dieser Internationalen Norm kompiliert werden.

  • Aber wenn Sie unique_ptr verwenden, erhalten Sie so ziemlich dasselbe, da nur ein unique_ptr das Eigentum an dem Objekt haben kann?

    – Tracer

    11. Juli 2014 um 6:56 Uhr

  • @ Tracer unique_ptr Wie jedes richtige C++ 11-Objekt kann das Eigentum an seiner Ressource nur übertragen werden, wenn es verschoben oder zugewiesen wird, wodurch sichergestellt wird, dass der Programmierer absichtlich eine übergeben muss std::move(sourceObject) oder eine vorübergehende, anstatt eine zu übergeben Wert und unintuitiv / unvorhersehbar durch die Kopierzuweisung mutiert … was, wie hier ausführlich betont wird, ein Kernproblem von war auto_ptr.

    – Unterstrich_d

    23. Februar 2016 um 0:15 Uhr


989290cookie-checkWarum ist es falsch, std::auto_ptr mit Standardcontainern zu verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy