warum ist der Destruktor-Aufruf nach dem std::move erforderlich?

In Der Programmiersprache C++ Edition 4 es ist ein Beispiel für ein Vektor-Implementierung, siehe entsprechende code am Ende der Nachricht.

uninitialized_move() initialisiert neuen T-Objekte in neuen Speicherbereich, indem Sie Sie aus den alten Speicherbereich. Dann ruft er den Destruktor auf den original T-Objekt, das verschoben-vom Objekt. Warum ist der Destruktor-Aufruf in diesem Fall notwendig?

Hier ist meine unvollständige Verständnis: die Verschiebung eines Objektes bedeutet, dass das Eigentum an den Ressourcen, die im Besitz der bewegt-vom Objekt übertragen werden, um die bewegt-zu-Objekt. Die Reste in die bewegt-vom Objekt sind einige mögliche Mitglieder von built-in Typen, die müssen nicht zerstört werden, Sie wird freigegeben, wenn der die vector_base b geht out of scope (innen reserve(), nach der swap() nennen). Alle Zeiger in die bewegt-vom Objekt gesetzt werden, um nullptr oder einen Mechanismus beschäftigt ist, fallen das Eigentum von bewegt-von der Objekt-auf diese Ressourcen, so dass wir sicher sind, warum dann rufen Sie den Destruktor auf eine aufgebraucht-Objekt, wenn die "vector_base b" Destruktor wird sowieso freigeben von Speicher nach der swap gemacht wird?

Verstehe ich die Notwendigkeit der explizite Aufruf des destruktors in den Fällen, wenn es aufgerufen werden muss, denn wir haben etwas zu zerstören (z.B. drop-Elemente), aber ich kann nicht erkennen, seine Bedeutung nach der std::move + Freigabe von vector_base. Ich Lesen Sie einige Texte über das Netz und ich sehe den Destruktor aufrufen, die bewegt-vom Objekt als ein signal (zu wem oder was?) dass die Lebensdauer des Objekts ist vorbei.

Bitte erläutern Sie mir, was eine sinnvolle Arbeit zu tun bleibt, um von den Destruktor? Danke!

Das code-snippet unten ist von hier aus http://www.stroustrup.com/4th_printing3.html

template<typename T, typename A>
void vector<T,A>::reserve(size_type newalloc)
{
    if (newalloc<=capacity()) return;                   //never decrease allocation
    vector_base<T,A> b {vb.alloc,size(),newalloc-size()};   //get new space
    uninitialized_move(vb.elem,vb.elem+size(),b.elem);  //move elements
    swap(vb,b);                                 //install new base 
} //implicitly release old space

template<typename In, typename Out>
Out uninitialized_move(In b, In e, Out oo)
{
    using T = Value_type<Out>;      //assume suitably defined type function (_tour4.iteratortraits_, _meta.type.traits_)
    for (; b!=e; ++b,++oo) {
        new(static_cast<void*>(&*oo)) T{move(*b)};  //move construct
        b->~T();                                //destroy
    }
    return oo;       
}
  • Dies ist eine generische Implementierung, die Sie nicht selbst jetzt, wenn T{move(*b)} fordert eine move-Konstruktor.
  • Glaube nicht, dass über den Umzug zu viel. Zur ersten Annäherung, Bewegung ist genauso wie das kopieren, und die Welt immer noch nach den gleichen Regeln spielt.
  • 🙂 aber Bewegung ist sehr wichtig, gerade weil es nicht kopieren, das ist zu teuer, um in einigen Fällen, so habe ich, um darüber nachzudenken, wie anders kopieren. Mit der Kopie kann ich entscheiden, legen Sie die original oder nicht, mit bewegen ich sagen "ich bin jetzt der neue Eigentümer von Ihr Eigentum und Sie sind erschöpft"
InformationsquelleAutor cvomake | 2013-12-14
Schreibe einen Kommentar