2010-02-07 18 views
3

Je veux créer un vecteur global de ma propre classe d'objets appelée "Person". Cependant, le compilateur dit queLa classe C++ Ref n'est pas membre de System :: IDisposable; problème d'implémenter IDisposable

error C2039: '{dtor}' : is not a member of 'System::IDisposable' 
1>  c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable' 

Alors je levai les yeux comment mettre en œuvre IDisposable (que je sais maintenant est utilisé principalement pour les ressources non gérés), mais encore ne peut pas sembler mettre en œuvre ce qui suit:

ref class Globals : System::IDisposable 
{ 
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>; 
    void Dispose() 
    { 
     delete person_data; 
    } 
}; 

Les 2 erreurs que je reçois sont:

error C2605: 'Dispose' : this method is reserved within a managed class 
1>  did you intend to define a destructor? 
error C3766: 'Globals' must provide an implementation for the interface method 'void System::IDisposable::Dispose(void)' 
1>  c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable::Dispose' 

Répondre

-1

De C++/CLI en action Le C++/CLI Éliminez modèle a ces règles (paraphrase):

  • Si une classe a un finaliseur ou un destructeur le compilateur génère Dispose(bool) qui appellera soit le finaliseur ou le destructeur basé sur la valeur bool.
  • S'il a juste un d'or (~ type) alors le compilateur appelle Dispose (true) pour que l''appel soit appelé.
  • Si elle a juste un finaliseur le compilateur appelle Dispose (false) de sorte que le finaliseur est appelé

également pour la deuxième règle (type!): Le compilateur mettra en œuvre l'interface IDisposable pour vous (en générant Dispose()). Il utilise ensuite SuppressFinalize pour s'assurer que le finaliseur n'est pas appelé. Je l'ai fait avec votre code et la seule façon de le compiler était de faire de person_data un membre d'instance. L'erreur que j'ai eu quand il était statique était error C2039: '{dtor}' : is not a member of 'System::IDisposable' ce qui n'a pas beaucoup de sens.

De même, avez-vous besoin de delete le vecteur person_data puisqu'il s'agit d'un objet géré? Peut-être que vous faites mais je n'ai pas assez utilisé le cliext pour le dire.

Modifier Peut-être le premier paragraphe de cette article a la réponse (moi qui souligne):

Lorsque vous déclarez une variable membre comme statique et lorsque l'application démarre, le compilateur crée une copie de ce membre. Ce membre est géré par le compilateur pendant que le programme est en cours d'exécution.Si vous déclarez une instance d'une classe, comme la variable du véhicule ci-dessus, l'organe statique est pas partie de l'objet: le compilateur crée et maintient le membre statique, que vous utilisiez ou non, si vous déclarez une variable de classe ou non.

+0

Merci pour votre réponse, je pense que cela va effectivement faire l'affaire. Aucune idée pourquoi cette erreur de destructeur continue à venir cependant. – Dororo

+0

Je n'arrive pas à trouver d'informations sur la libération des membres statiques dans les destructeurs ou les finaliseurs. Peut-être que quelqu'un connaît la réponse et partagera. – cmw

+0

Les membres statiques sont initialisés par le .cctor, pas au démarrage de l'application –

0

Utilisez un destructor. En C++/CLI ~ ClassName() est Dispose() et! ClassName() est équivalent à C# ~ ClassName(). Dans votre cas:

ref class Globals : System::IDisposable 
{ 
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>; 
    void ~Globals() 
    { 
     delete person_data; 
    } 
}; 
+0

Le compilateur dit ensuite qu'un destructeur ne peut pas avoir un type de retour. Supprimer 'void' rend cependant le compilateur incapable de reconnaître la fonction comme une implémentation de IDisposable (puisqu'elle est de la forme void func (void) vraisemblablement?) – Dororo

3

Vous ne devez pas tirer explicitement de IDisposable. Suite à la MSDN doco, utilisez le schéma suivant:

ref class Globals 
{ 
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>; 
    !Globals() // finalizer 
    { 
     delete person_data; 
    { 
protected: 
    ~Globals() // destructor calls finalizer 
    { 
     this->!Globals(); 
    } 
}; 
+0

Merci pour votre aide, mais j'ai toujours une erreur à: static cliext :: vector person_data = gcnew cliext :: vecteur ; Le compilateur indique que le destructor est pas membre de IDisposable: 1> Erreur C2039: '{dtor}': n'est pas membre du 'système :: IDisposable' 1> c: \ windows \ microsoft.net \ framework \ v2.0.50727 \ mscorlib.dll: voir la déclaration de 'System :: IDisposable' Même après s'être assuré que la classe Person est effectivement IDisposable, elle refuse toujours de se compiler. – Dororo

+0

La seule façon de le compiler est de supprimer le mot-clé 'static' de person_data. Dès que vous avez un membre statique de type cliext :: vector vous obtenez cette erreur - J'ai essayé de supprimer person_data et de le remplacer par cliext :: vector int_data = gcnew cliext :: vector ; et toujours eu la même erreur! C'est au-delà de mes compétences. – mcdave

+0

vous ne pouvez pas supprimer ce qui n'est pas un handle –

0

Vous n'avez pas besoin d'implémenter Dispose() vous-même, directement ou via un destructeur. Le destructeur implicitement généré détruit déjà tous les objets membres. L'interface IDisposable sera ajoutée automatiquement, ne le mentionnez pas explicitement. Ensuite, vous devez vous décider si person_data est un handle (qui doit être défini sur une instance créée avec gcnew) ou une sémantique d'objet membre (comme la sémantique de la pile, le constructeur est automatiquement appelé par le constructeur du objet parent, le destructeur appelé automatiquement lorsque la durée de vie de l'objet parent se termine, et vous utilisez "." au lieu de "->" pour accéder aux membres). Etes-vous sûr de vouloir disposer d'une copie de person_data partagée entre toutes les instances de "Globals", mais détruite par la première instance, laissant toutes les autres instances contenant une référence invalide (référence à un objet disposé)? On dirait que vous essayez d'utiliser un anti-pattern Singleton ici, n'est-ce pas?