Lorsque je compile le code C++/CLI suivant dans VS2008, un avertissement d'analyse de code CA1001 s'affiche.Pourquoi le GC ne dispose-t-il pas automatiquement les membres de ma classe?
ref class A
{
public:
A() { m_hwnd = new HWND; }
~A() { this->!A(); }
protected:
!A() { delete m_hwnd; }
HWND* m_hwnd;
};
ref class B
{
public:
B() { m_a = gcnew A(); }
protected:
A^ m_a;
};
avertissement: CA1001: Microsoft.Design: Mettre en oeuvre IDisposable sur 'B', car il crée membres des types IDisposable suivants: 'A'.
Pour résoudre cet avertissement, je dois ajouter ce code à la classe B:
~B() { delete m_a; }
Mais je ne comprends pas pourquoi. La classe A implémente IDisposable via son destructeur (et le finaliseur).
Donc, à chaque fois que A récupère des ordures, alors le finaliseur ou le destructeur de A sera appelé, libérant ses ressources non managées.
Pourquoi B doit-il ajouter un destructeur pour appeler 'delete' sur son membre A?
Le GC appellera-t-il seulement le destructeur de A si B appelle explicitement "delete m_a"?
Modifier: il semble que cela fonctionne automatiquement si vous utilisez la méthode « de sucre de syntaxe » de déclarer l'Un membre, comme celui-ci:
ref class B
{
public:
B() { }
protected:
A m_a;
};
mais ce n'est pas toujours possible. Pourquoi le GC n'est-il pas assez intelligent pour disposer automatiquement du pointeur de référence managé de A ^, alors que personne d'autre n'a de pointeur dessus?
Merci, et il est vrai que je pourrais utiliser la syntaxe de la méthode du sucre - en fait, si je fais cela, je n'ai pas besoin d'implémenter un destructeur du tout (enfin, il supprime l'avertissement). Mais dans certaines/la plupart des situations, vous ne pouvez pas utiliser la syntaxe de la méthode du sucre, vous ne pouvez stocker que le pointeur de référence géré. Je veux savoir pourquoi le GC a besoin d'un appel explicite pour supprimer le pointeur de référence géré afin de disposer de l'objet géré. – demoncodemonkey
"Beaucoup de classes peuvent contenir le même pointeur A ^, il n'y a aucun moyen de savoir lequel devrait appeler le destructeur" << Le GC devrait être capable de savoir lequel était le dernier, et quand le dernier est libéré alors il devrait appeler le destructeur. Il semblerait que le GC n'est pas aussi génial qu'il pourrait l'être ... – demoncodemonkey
Je vais vérifier si je peux refactoriser mon code comme vous l'avez dit. – demoncodemonkey