Disparition de pointeurs sur classes derivees [Résolu]

Signaler
Messages postés
7
Date d'inscription
lundi 2 octobre 2006
Statut
Membre
Dernière intervention
20 novembre 2006
-
Messages postés
7
Date d'inscription
lundi 2 octobre 2006
Statut
Membre
Dernière intervention
20 novembre 2006
-
Bonjour a tous !
Alors voilà, j'ai un petit probleme de pointeurs sur classes derivées qui disparaissent des la sortie de leur espace de construction.

-------------- .h

class Mere{
    public :
       virtual int GetId(){ return -1; }
};

class Fille : public Mere {
    public :
       virtual int GetId(){ return 5; }
};

class Interface{
    public :
       void Action();  /** est appelée lors d'un evenement utilisateur */
       Mere* pointeur;
};

------------- .cpp

Interface::Interface(){
    pointeur = new Fille();
    pointeur->GetId() // Fonctionne
};

Interface::Action(){
    pointeur->GetId() // Segmentation Fault
};

En gros, j'ai une classe Mere, et une classe Fille derivée de Mere. Je cree un objet Fille, que je veut pouvoir utiliser durant tout le programme, j'en stocke donc l'adresse. Mais je ne veut pas avoir a connaitre a l'avance l'existence de cet objet Fille, donc je stocke un poinetur de type (Mere*).
Le probleme, c'est que des que je sort de l'espace ou cet objet a été créé, mon pointeur semble ne plus etre valide.
J'ai tenté de stocker ce pointeur avec Boost, avec wxWidget, avec les conteneurs standars, des tableaux et autres. Rien n'y fait. J'ai beau tenter d'approfondir les mecanismes de l'heritage, je n'arrive pas a comprendre pourquoi mon pointeur devient invalide. Mon objet Mere derive lui-meme d'un objet wxWidget, qui lui semble toujours valide alors meme que mon pointeur ne l'est plus.

Si vous pouviez m'indiquer ce que je fait de travers, ou bien un mecanisme important que je n'ai peut etre pas bien compris, ce serais tres sympa^^

Merci d'avance.

7 réponses

Messages postés
7
Date d'inscription
lundi 2 octobre 2006
Statut
Membre
Dernière intervention
20 novembre 2006

Probleme resolut !

J'ai retravaillé mes classes pr faire remonter la classe wxTreeCtrl de wxWidget au niveau de ma derniere classe derivée.
Le compilateur m'a indiqué une ambiguité au niveau de la fonction GetName(), en effet, celle-ci était deja definie par une classe de base de wxTreeCtrl.
Le compilateur ne l'avait probablement pas detecté a cause des quelques niveau hierarchique separant le GetName() de wxWidget et le mien.

wxObject->wxWindow->wxControl->wxTreeCtrl->List_Base->List_Main

C'était donc simplement un conflit non repere par gcc.
Me voilà prevenu^^
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Est-ce que tu crée bien ton objet sur le tas? Sinon, c'est normal qu'il ne soit plus valide à un moment donnéIl faut donc faire pointeur new Fille(...), et non Fille f Fille(); pointeur = &f; (à moins que f ne soit déclaré en global, ou en local dans main)

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
7
Date d'inscription
lundi 2 octobre 2006
Statut
Membre
Dernière intervention
20 novembre 2006

Et bien je declare le pointeur dans une classe, ensuite je ne l'utilise que dans cette classe.
Je le definit dans le constructeur de la classe.

class Interface{
    public :
       void Action();  /** est appelée lors d'un evenement utilisateur */
       Mere* pointeur;
};

Interface::Constructeur(){
    pointeur = new Fille();
    pointeur->GetId() // Fonctionne
};

// Action() est bien lancé apres que le pointeur soit correctement definit
Interface::Action(){
    pointeur->GetId() // Segmentation Fault
};
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Aucun problème pour moi
Montre un peu plus de code sinon c'est difficile de savoir d'ou vient ton problème

#include
using namespace std;

class Mere{
public :
  virtual int GetId(){ return -1; }
};

class Fille : public Mere {
public :
  virtual int GetId(){ return 5; }
};

class Interface{
  Mere* pointeur;
public :
  Interface::Interface()
  {
    pointeur = new Fille();
    pointeur->GetId();
  }

  int Action()
  {
    return pointeur->GetId();
  }
};

int main()
{
  Interface i = Interface();
  cout << i.Action() << endl;
}

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
7
Date d'inscription
lundi 2 octobre 2006
Statut
Membre
Dernière intervention
20 novembre 2006

// list_base.h





class List_Base : public wxTreeCtrl{
   public :
      List_Base() : wxTreeCtrl( ){};
      virtual wxString& GetName(){ return name; };

      wxString name;

   private :
      DECLARE_DYNAMIC_CLASS( List_Base)
};

class List_Main :  public List_Base{

   DECLARE_DYNAMIC_CLASS( List_Main)

   public :
      List_Main() : List_Base(){
         name = "Liste principale";
      };
      bool Init();
      wxString& GetName(){ return name; };

      wxString name;

   protected :
      DECLARE_EVENT_TABLE();
};

// list.h
class List : wxEvtHandler{

   public :
      List(){
            list_ptr.reset( new List_Main() );

            // fonctionne

           wxMessageBox( list_ptr->GetName() );
      };
       /** fonction appelée en cours d'execution par l'utilisateur */
      void Action() {
          // fonctionne


           wxMessageBox( list_ptr->GetName() );
       };
       /** pointeur List_Main*, qu'il soit gere par Boost ou autre chose ne change rien */
      boost::scoped_ptr<List_Main> list_ptr;
};

Voilà, il y a donc ma classe de base List_Base, ma classe derivée List_Main, Ma classe qui doit gerer mes classes derivées List.
Mon pointeur list_ptr, et ma fonction Action() qui est appelée en cours d'execution par l'utilisateur. Entre List() et Action() il ne se passe rien de special.
Les instructions sont simples, l'absence de DECLARE_DYNAMIC_CLASS (wxWidget) de change rien. L'utilisation des pointeurs stl ne change rien non plus.
Messages postés
7
Date d'inscription
lundi 2 octobre 2006
Statut
Membre
Dernière intervention
20 novembre 2006

void Action() {
     // ne fonctionne pas [ rectification du post precedent ]
     wxMessageBox( list_ptr->GetName() );
};
Messages postés
7
Date d'inscription
lundi 2 octobre 2006
Statut
Membre
Dernière intervention
20 novembre 2006

Si je fait ( (wxTreeCtrl*)list_ptr )->GetCount(); j'arrive a utiliser le pointeur. Le pointeur fonctionne donc pour les classes derivées créée par la librairie wxWidget.
On dirait que les informations de type de mes classes se sont perdues en sortant de ma fonction constructeur.