2016-04-30 5 views
0

J'ai besoin d'une classe noncopyable qui a un destructeur déclaré, et une approche naïve ne fonctionne pas: voir https://ideone.com/mU8aoc. Quel est le problème avec le destructeur, pourquoi le déplacement ne fonctionne pas de la même manière que sans? Et bien sûr, comment le réparer?`non inviolable` avec un destructeur personnalisé

Pour référence, le code complet (même que par le lien ideone ci-dessus):

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

Définir "custom destructor". Tous les destructeurs sont "personnalisés", pour chaque classe. –

+0

Par "custom", je voulais dire un destructeur explicitement déclaré dans la classe 'C' (voir le code) - sans cela, l'exemple compile. – aplavin

+0

Une super-classe ne peut pas forcer une sous-classe à avoir un destructeur explicitement déclaré. Une super-classe peut forcer une sous-classe à implémenter une méthode virtuelle pure. Mais les destructeurs ne sont pas des méthodes. Chaque classe doit avoir un destructeur, si ce n'est pas le cas, il obtient un destructeur par défaut. Il n'y a pas de "destructeur personnalisé". Il n'y a qu'une seule façon de détruire une instance de classe. Ce qu'on appelle communément un «destructeur» est un morceau de code arbiraire qui est exécuté avant qu'une instance de classe ne soit réellement détruite. Et comment une instance de classe est détruite est explicitement définie par le standard C++. –

Répondre

1

Pour votre code fonctionne, class C doit être mobile. Lorsqu'il n'a pas de destructeur déclaré, il obtient un constructeur de mouvement implicite généré par le compilateur (et un opérateur d'assignation de mouvement). Mais quand il a un destructeur déclaré ("custom" dans votre langage), le constructeur de déplacement (et l'opérateur d'affectation de mouvement) ne sont plus fournis implicitement. C'est pour votre sécurité: il est supposé que si vous avez besoin d'un destructeur explicite, vous aurez également besoin de fonctions de déplacement explicites.

Référence: http://en.cppreference.com/w/cpp/language/move_constructor