2016-04-30 12 views
0

Ich brauche eine noncopyable Klasse, die eine deklarierte destructor hat, und naive Ansatz funktioniert nicht: https://ideone.com/mU8aoc sehen. Was ist das Problem mit dem Destruktor, warum bewegt sich nicht so wie ohne es? Und natürlich, wie man es repariert?`noncopyable` mit benutzerdefinierten destructor

Als Referenz der vollständige Code (wie bei der ideone Link oben):

class noncopyable { 
public: 
    noncopyable(noncopyable &&) noexcept; 

    noncopyable &operator=(noncopyable &&) noexcept; 

protected: 
    noncopyable() = default; 

    ~noncopyable() = default; 

    noncopyable(const noncopyable &) = delete; 

    noncopyable &operator=(const noncopyable &) = delete; 
}; 

class C: noncopyable { 
public: 
    // compiles if this line is uncommented 
    // C(C&& c); 

    C() {} 

    // also compiles if this is commented 
    ~C() {} 
}; 

C a() { 
    return {}; 
} 

C b() { 
    return a(); 
} 

int main() { 
    return 0; 
} 
+0

definieren "custom destructor". Alle Destruktoren sind für jede Klasse "benutzerdefiniert". –

+0

von „custom“ Ich destructor bedeutete explizit in der 'C' Klasse deklariert (den Code sehen) - ohne es kompiliert das Beispiel. – aplavin

+0

Eine Superklasse kann eine Unterklasse nicht dazu zwingen, einen explizit deklarierten Destruktor zu haben. Eine Oberklasse kann eine Unterklasse dazu zwingen, eine reine virtuelle Methode zu implementieren. Aber Destruktoren sind keine Methoden. Jede Klasse muss einen Destruktor haben, andernfalls einen Standarddestruktor. Es gibt keinen "benutzerdefinierten Destruktor". Es gibt nur eine Möglichkeit, wie eine Klasseninstanz zerstört wird. Was man gemeinhin als "Destruktor" bezeichnet, ist ein beliebiger Codeabschnitt, der ausgeführt wird, bevor eine Klasseninstanz wirklich zerstört wird. Und wie eine Klasseninstanz zerstört wird, wird explizit vom C++ - Standard definiert. –

Antwort

1

Für Ihren Code zu arbeiten, muss class C beweglich sein. Wenn es keinen deklarierten Destruktor hat, erhält es einen vom Compiler erzeugten impliziten Move-Konstruktor (und einen Zuweisungsoperator). Aber wenn es ein deklarierte („custom“ im Sprachgebrauch) destructor hat, der Umzug Konstruktor (und bewegt Zuweisungsoperator) nicht mehr implizit zur Verfügung gestellt. Dies dient Ihrer Sicherheit: Wenn Sie einen expliziten Destruktor benötigen, wird davon ausgegangen, dass Sie auch explizite Verschiebefunktionen benötigen.

Referenz: http://en.cppreference.com/w/cpp/language/move_constructor