2017-04-15 1 views
0

J'utilise des classes d'amis et je veux utiliser le destructeur de rec lorsque j'appelle DeleteItem de ma classe de liste. Cependant, il y a un pointeur pointant vers l'enregistrement que je veux supprimer, donc je ne sais pas comment appeler le destructeur pour qu'il fasse ce que je veux. Classes:appeler le destructeur d'une classe d'amis

class rec 
    { 
      friend class list; 
     private: 
      char * id; 
      char firstname[15]; 
      char lastname[15]; 
      int ar[10]; 
      rec* prev; 
      rec* next; 
     public: 
      void SetData (char * id_in, char * fn, char * ln, int * ans_in); 
       rec(char *i, char *fn, char *ln, int *a); 
       rec(); 
      void operator= (const rec& r); 
       rec (const rec& r); 
      void Print(); 
       ~rec(); 
    }; 

    class list 
    { 
     private: 
      rec* first; 
      rec* last; 
     public: 
      int AddItem(rec r); 
      int DeleteItem (char* delid); 
      void PrintList(int order); 
      int ReadData(char *inanswer, char *inkey); 
      int WriteData(char *answer, char *key); 
       list(); 
      void operator= (list l); 
     private: 
      int CheckDuplicate(rec r); 
      void DeleteData(); 
      int Count(char *filename); 
    }; 

~ rec()

 rec :: ~rec() 
{ 
    if (id != NULL) 
    { 
     delete [] id; 
    } 
} 

DeleteItem (Snipet)

int list :: DeleteItem(char *delid)  
{ 
    int id_counter; 
     rec *current = first; 
     while (current || current == NULL) 
      { 
      if (current == NULL) 
       { 
       return 0; 
       } 
      else 
       { 
       id_counter = strcmp(current -> id, delid);    
       if (id_counter != 0) 
        { 
        current = current -> next; 
        } 
       else 
        { 
        if (current == first && current != last)   
         { 
         ~rec();   //Here 
         first = current -> next; 
         delete current; 
         first -> prev = NULL; 
         return 1; 
         } 

article Supprimer compilera bien si je mets manuellement dans delete[] current ->id; mais ce que cela lorsque je tente de compiler tel quel

list.cpp:292: error: no match for ‘operator~’ in ‘~rec()’ 
/usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/ios_base.h:105: note: candidates are: std::_Ios_Fmtflags std::operator~(std::_Ios_Fmtflags) 
/usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/ios_base.h:145: note:     std::_Ios_Openmode std::operator~(std::_Ios_Openmode) 
/usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../../../include/c++/4.3.0/bits/ios_base.h:183: note:     std::_Ios_Iostate std::operator~(std::_Ios_Iostate) 

Est-ce mon destructeur qui doit être réparé ou est-ce quelque chose à faire dans DeleteItem?

+0

Veuillez formater correctement votre code pour qu'il soit lisible ici. –

+0

Vous envisagez de résoudre votre problème sans "ami", car c'est une mauvaise habitude – 21koizyd

+4

Vous ne devriez presque jamais appeler un destructeur explicitement. Certainement pas pour cette classe. Vous devriez également éviter les pointeurs et les tableaux bruts. Utilisez std :: string, std :: vector et std :: shared_ptr/std :: unique_ptr à la place. –

Répondre

2

Pour appeler un destructeur, la syntaxe est current->~rec(), mais dans la plupart des cas, vous ne devez pas appeler directement un destructeur en C++. En appelant le delete current, le C++ appelle automatiquement le destructeur avant de désallouer sa mémoire.

Dans votre cas, que vous utilisez également delete après avoir appelé ~rec(), votre destructor sera appelé deux fois, donc vous entraîner à une corruption à double libre comme votre constructeur tente de libérer id mémoire.

Conseil: Pour éviter d'utiliser la classe d'amis, dans votre cas, next et prev membres sont liés à la list, et non à rec classe. Ainsi, votre list classe pourrait avoir une classe de décorateur imbriquée qui enveloppera votre rec classe comme:

class list 
{ 
    struct item { 
     rec* value; 
     rec* prev; 
     rec* next; 
    }; 
    item * first; 
    item * last; 
public: 
    // ... 
}; 

alors la logique de votre liste sera bien isolée de la logique de votre classe rec.