2017-10-05 9 views
0

This apparaît similaire à l'endroit où je suis dirigé ainsi que this question.C++ classe intérieure Destructor Resource Management

Considérez ce qui suit

template<typename T> 
class A 
{ 

private: 

    class B 
    { 

    private: 

     B* link; 

    public: 

     B(); 
     ~B(); 

    }; 

    B* head; 

public: 

    A(); 
    ~A(); 
}; 

Le crée au-dessus de la structure ci-dessous assume la fonction de créer et de relier chaque B est déclarée et définie

EI6yn6W

Si j'effectue l'opération comme indiqué ci-dessus , puis

B* position = head; 
position = head->link; 
head->link = nullptr; 
delete[] head; 
head = position; 

Je comprends que l'appel du destructeur de classe interne entraînera l'appel du destructeur de classe externe. Ai-je correctement géré la collecte des ordures la ressource x ou ai-je fait quelque chose de non défini?

+1

Pourquoi pensez-vous d'appeler la destructor classe interne (que vous ne faire dans l'échantillon que vous avez posté) aura comme conséquence le destructeur de classe externe appelé? C'est l'inverse, non? – bnaecker

+1

"Ai-je fait quelque chose de non défini?" Oui. L'appel 'delete []' sur un type non-tableau est UB. – bnaecker

+0

Je pense que vous confondez la classe "interne" avec la classe "base". Si la classe de base a un destructeur virtuel, alors le destructeur de la classe dérivée ("externe") sera appelé quand le destructeur de classe de base ("interne") sera appelé. Et il n'y a pas de "collecte des ordures" en C++. – VTT

Répondre

0

Dans le code fourni, la classe interne n'appelle pas le destructeur de la classe externe, et elle ne devrait pas l'être, car la classe externe n'a qu'un pointeur vers la classe interne en tant que membre.

La récupération de place n'est pas nécessaire si A est créé avec une durée de stockage automatique (c'est-à-dire en tant que variable sans nouvelle). Il sera détruit quand il sort de la portée. La règle générale est que chaque new doit avoir un delete correspondant.

Pour illustrer, j'ai simplifié le code, placé le code de suppression de nœud dans une fonction de membre et a fourni un exemple simple de son utilisation:

struct A 
{ 
    struct B 
    { 
     B* link; 
    }; 
    B* head; 
    void delete_head() 
    { 
     B* position = head; 
     position = head->link; 
     //head->link = nullptr; // not needed, it is being deleted anyway 
     delete head; // not delete[]! This isn't an array pointer 
     head = position; 
    } 
}; 

int main() 
{ 
    A a; 
    a.head = new A::B; // create head node 
    a.head->link = new A::B; // create node 
    a.delete_head(); // call A::~B() 
    a.delete_head(); // call A::~B() 
    // no more nodes in a, but A's destructor is not yet called 
} // A::~A() is called here