2016-07-07 15 views
1

Anfangs dachte ich, dass move constructor den temporären Objektdestruktor nicht aufrufen würde, aber wenn ich es versuche, ruft er den Destruktor auf. Wenn wir also die Daten von move constructor stehlen, bekomme ich doppelten Löschfehler.Move constructor und double delete

#include <iostream> 
using namespace std; 

class A 
{ 
    public: 
    A() 
    : name("default") 
    { 
     cout<<"i am default\n"; 
     data = new char[20]; 
    } 

    A(A&& t) 
    : name("move") 
    { 
     data = t.data; 
     cout<<"i am move\n"; 
    } 

    ~A() 
    { 
     delete data; 
     cout<<"I am done:"<<name<<endl; 
    } 

    char * data; 
    string name; 
}; 

A getA() 
{ 
    A obj; 
    return obj; 
} 

int main() 
{ 
    A test(std::move(getA())); 
} 
+6

Nun, Ihr Umzug Konstruktor gebrochen ist. Aber was ist deine Frage? – juanchopanza

+1

Sie * sicher * Sie haben diese Daten gestohlen? Ich bin mir ziemlich sicher, dass dein Originalobjekt immer noch glaubt, dass es ihm gehört, zumal du nichts getan hast, um es anders in deinem mv-ctor zu erzählen. – WhozCraig

+0

Ich bekomme doppelte Fehler löschen, wenn ich dies ausführen, was wird der Grund sein? –

Antwort

11

Das ist, weil Sie nicht wirklich sind „stehlen“, du bist nur zu kopieren, und so werden Sie 2 mal den gleichen Zeiger löschen, wie Sie bemerkt.

Um die Daten zu "stehlen", setzen Sie die Originaldaten auf nullptr, da sie nicht mehr zu diesem Objekt gehören.

A(A&& t) 
: name("move") 
{ 
    data = t.data; 
    t.data = nullptr; //'t' doesn't own its data anymore 
    cout<<"i am move\n"; 
} 

Sie könnten auch std::swap (dank @RemyLebeau) verwenden:

A(A&& t) : name("move"), data(nullptr) 
{ 
    std::swap(data, t.data); 
    cout << "i am move\n"; 
} 
+4

Verwenden Sie stattdessen 'std :: swap()': 'A (A && t): Name (" move "), Daten (nullptr) {std :: swap (Daten, t.data); cout << "ich bin move \ n"; } ' –

+1

Oder etwas zarter,' A (A && t): Name ("move"), Daten (std :: exchange (t.data, nullptr)) {/ * ... * /} ' –