Was kann ich mit einem verschobenen Objekt tun?

Lesezeit: 4 Minuten

Definiert der Standard genau, was ich mit einem Objekt tun kann, nachdem es entfernt wurde? Früher dachte ich, dass alles, was Sie mit einem verschobenen Objekt tun können, es zerstören soll, aber das würde nicht ausreichen.

Nehmen Sie zum Beispiel die Funktionsvorlage swap wie in der Standardbibliothek definiert:

template <typename T>
void swap(T& a, T& b)
{
    T c = std::move(a); // line 1
    a = std::move(b);   // line 2: assignment to moved-from object!
    b = std::move(c);   // line 3: assignment to moved-from object!
}

Offensichtlich muss eine Zuweisung auf ausgelagerte Objekte möglich sein, sonst würden die Zeilen 2 und 3 versagen. Was kann ich also sonst noch mit verschobenen Objekten machen? Wo genau finde ich diese Angaben in der Norm?

(Übrigens, warum ist es T c = std::move(a); anstatt T c(std::move(a)); in Zeile 1?)

Was kann ich mit einem verschobenen Objekt tun
Howard Hinnant

17.6.5.15 [lib.types.movedfrom]

Objekte von Typen, die in der C++-Standardbibliothek definiert sind, können aus (12.8) verschoben werden. Bewegungsoperationen können explizit angegeben oder implizit generiert werden. Sofern nicht anders angegeben, werden solche ausgelagerten Objekte in einen gültigen, aber nicht spezifizierten Zustand versetzt.

Wenn sich ein Objekt in einem nicht spezifizierten Zustand befindet, können Sie jede Operation für das Objekt ausführen, die keine Vorbedingungen hat. Wenn Sie eine Operation mit Vorbedingungen ausführen möchten, können Sie diese Operation nicht direkt ausführen, da Sie nicht wissen, ob der Status „unspecified“ des Objekts die Vorbedingungen erfüllt.

Beispiele für Operationen, die allgemein keine Voraussetzungen haben:

  • Zerstörung
  • Abtretung
  • const Beobachter wie z get, empty, size

Beispiele für Operationen, die allgemein haben Vorraussetzungen:

  • Dereferenzierung
  • Pop zurück

Diese Antwort erscheint nun im Videoformat hier: http://www.youtube.com/watch?v=vLinb2fgkHk&t=47m10s

  • Aber ich könnte die Vorbedingungen einfach wie bei jedem anderen Objekt überprüfen, oder?

    – fredoverflow

    11. August 2011 um 15:17 Uhr

  • @FredOverflow Solange diese Prüfungen selbst natürlich keine Vorbedingungen haben.

    – Christian Rau

    11. August 2011 um 15:18 Uhr

  • @Chris: Aber wie unterscheidet sich das von einem normalen, nicht bewegten Objekt?

    – fredoverflow

    11. August 2011 um 15:25 Uhr

  • Vielleicht sollte das eine eigene Frage sein, aber heißt das: wenn ich einen String mit habe char* buffer; und int length; Mitglieder, dann muss mein Bewegungskonstruktor/meine Zuweisung den Wert von beiden tauschen (oder setzen)? Oder wäre es in Ordnung, wenn die Länge nicht angegeben wäre (was bedeutet, dass empty und size bedeutungslose Werte zurückgeben)?

    – Onkel Bens

    11. August 2011 um 15:32 Uhr

  • @6502: Sie ergeben keinen Sinn. Eine C++03-Klasse verstößt nicht gegen den C++0x-Standard, weil ein move ctor falls generiert würde gegen die Norm verstoßen. Und C++03-Code würde diese Klasse nicht verschieben, also gibt es keinen Grund, einen Move-Ctor zu generieren.

    – MSalter

    12. August 2011 um 9:27 Uhr

1647093612 745 Was kann ich mit einem verschobenen Objekt tun
Hündchen

Ausgelagerte Objekte befinden sich in einem nicht spezifizierten, aber gültigen Zustand. Das deutet darauf hin, dass das Objekt zwar nicht mehr viel leisten kann, aber alle seine Mitgliedsfunktionen immer noch ein definiertes Verhalten zeigen sollten – einschließlich operator= – und alle seine Mitglieder in einem definierten Zustand – und es muss immer noch zerstört werden. Der Standard enthält keine spezifischen Definitionen, da er für jeden UDT eindeutig wäre, aber Sie können möglicherweise Spezifikationen für Standardtypen finden. Einige ähnliche Container sind relativ offensichtlich – sie verschieben einfach ihren Inhalt und ein leerer Container ist ein wohldefinierter gültiger Zustand. Primitive ändern das Objekt, aus dem es verschoben wurde, nicht.

Randnotiz: Ich glaube schon T c = std::move(a) Wenn also der Move-Konstruktor (oder der Copy-Konstruktor, wenn kein Move angegeben ist) explizit ist, schlägt die Funktion fehl.

  • Nicht alle seiner Mitgliedsfunktionen wird definiertes Verhalten zeigen. Nur die ohne Vorbedingungen. Zum Beispiel möchten Sie wahrscheinlich nicht pop_back ein Umzug vector. Aber ob es das ist, kannst du sicher herausfinden empty().

    – Howard Hinnant

    11. August 2011 um 14:40 Uhr

  • @Howard Hinnant: pop_back aus einem leeren vector hat sowieso undefiniertes Verhalten, aus dem Gedächtnis, also bin ich mir ziemlich sicher, dass pop_back von einem bewegten Vektor, der undefiniertes Verhalten zeigt, konsistent ist.

    – Hündchen

    11. August 2011 um 14:50 Uhr

  • Wir sprechen über verschobene Objekte. Keine Objekte, von denen bekannt ist, dass sie sich in einem leeren Zustand befinden. Ausgelagerte Objekte haben einen unspezifizierten Zustand (sofern natürlich nicht anders angegeben). [lib.types.movedfrom]

    – Howard Hinnant

    11. August 2011 um 15:11 Uhr

  • @Howard Nicht spezifiziert, aber gültig, also pop_back verhält sich immer noch wie auf jedem gültigen Vektor (kann es sogar ein leerer Vektor sein).

    – Christian Rau

    11. August 2011 um 15:15 Uhr

  • was bedeuten unspezifiziert und gültig in diesem zusammenhang?

    – Ankur S

    19. Juni 2018 um 12:41 Uhr

993820cookie-checkWas kann ich mit einem verschobenen Objekt tun?

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

Privacy policy