IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Héritage Virtuel et SDL


Sujet :

SDL

  1. #1
    Futur Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Points : 5
    Points
    5
    Par défaut Héritage Virtuel et SDL
    Bonjour,

    J'ai cette classe mère:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Widget
    {
    public:
        Widget();
        ~Widget();
        virtual void affiche();
    };
    qui est héritée par cette classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Bouton: public Widget
    {
    public:
        void affiche();
    };
    J'ai un std::map de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<std::string, Widget*> mWidgets;
    dans ce map je range un pointeur vers un objet bouton.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Bouton * objetBouton;
    objetBouton = new Bouton;
    mWidget["bouton"] = objetBouton;
    puis j'apelle dans un autre thread fait de type SDL_Thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (ptrMWidget = mWidget.begin(); ptrMWidget != mWidget.end(); ++ptrMWidget)
    {
            ptrMWidget->second->affiche(); //C'est ici que survient l'érreur de segmentation
    }
    Et j'obtient ceci lors de l'éxécution du programme :
    Fatal signal: Segmentation Fault (SDL Parachute Deployed)

    Si je retire virtual devant la fonction memebre de la classe mère je n'ai plus l'érreur. Mais ce qui m'intéresse est bien sur de pouvoir redéfinir la classe mère ^^·

    Si quelqu'un peut m'aider à comprendre d'ou provient l'érreur. Il se peut que ce soit du au thread, dans ce cas si il y as un moyen de procédé autrement sa m'intéresse aussi.

    Merci d'avance

  2. #2
    Rédacteur
    Avatar de MrDuChnok
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2002
    Messages
    2 112
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 112
    Points : 4 240
    Points
    4 240
    Par défaut
    Salut,
    Peut tu nous donner le code de la méthode "void affiche();" de ta classe Bouton ?

    Quand tu dis que tu accède à ta liste depuis un autre Thread, tu es bien sûr que ta liste est partagée entre ces deux threads ?

    merci !
    Si vous jugez mon post utile dans la résolution de votre problème, n'hésitez pas à utiliser le système de vote afin d'améliorer la qualité du forum

  3. #3
    Futur Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Pour la classe bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Bouton::affiche()
    {
        std::cout << "Coucou de Bouton" << std::endl;
    }
    Pour la classe widget :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Widget::affiche()
    {
        std::cout << "Hello World" << std::endl;
    }
    mais le problème se situe au niveau de la fonction membre virtuelle.
    Car si je déclare affiche comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Widget
    {
    public:
    Widget();
    ~Widget();
    void affiche();
    };
    Eh bien j'ai "Hello World" à l'écran.

    Et si je veu "Coucou de Bouton", j'appelle la méthode affiche de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((Bouton *)ptrMWidget->second)->affiche();
    Mais je n'aurais pas redéfini la fonction membre affiche de la classe mère.

    Merci.

  4. #4
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Chez moi je n'ai pas de problème avec un code du genre. Il faudrait qu'on voit comment tu passes ta map à ton thread. Et aussi au pif peut-être que tu détruit tes éléments avant la fin du thread ?
    Fiquet
    - FAQ SDL
    - FAQ C++

  5. #5
    Futur Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Bonjour et surtout merci pour votre courage à m'aidé dans cette peine

    Mais je pense que j'ai du mal m'exprimer.
    Donc avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Widget
    {
    public:
    Widget();
    ~Widget();
    void affiche();
    };
    Sa fonctionne tres bien. mais j'ai voulu que la classe fille redéfinisse cette méthode. Alors j'ai écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Widget
    {
    public:
        Widget();
        ~Widget();
        virtual void affiche();
    };
    Mais lorsque j'apelle la fonction affiche j'ai à présent cette érreure :
    Fatal signal: Segmentation Fault (SDL Parachute Deployed)
    Je voulait donc comprendre pourquoi le fait de rendre une fonction virtuelle pouvait faire une telle érreure.

    Sinon pour Fiquet, la map est contenue dans un vecteur qui est une donnée membre publique d'une autre classe.
    J'accède à la donnée membre grace à un pointeur passé en paramêtre au Thread.
    Je pense qu'il sera plus simple de joindre le code complet du thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    typedef std::map<std::string, Widget*> mWidgets;
    bool Trun;
    int Tdelai;
    SDL_Surface *screen;
    
    int top(void * argObjEcran)
    {
        Ecran * objEcran = (Ecran *)argObjEcran; //Pointeur vers la classe qui contient le vecteur.
        mWidgets objMWidget; //objet qui contiendra la map
        mWidgets::iterator ptrMWidget;
        while(Trun)
        {
            SDL_Delay(Tdelai); //pause entre chaque affichage
            //Boucle qui parcoure le vecteur
            for(int iCouches=0; iCouches < objEcran->vCouches.size(); iCouches++)
            {
                //Recopie de l'objet map
                objMWidget = objEcran->vCouches[iCouches];
                //Parcour de la map
                for (ptrMWidget = objMWidget.begin(); ptrMWidget != objMWidget.end(); ++ptrMWidget)
                {
                    //Et hop on appelle la fonction membre affiche
                    ptrMWidget->second->affiche(); //Segmentation Fault si affiche est virtuelle.
                }
            }
        }
    }
    Mais il faut garder à l'esprit que le code avec la donnée membre affiche déclarée de cette manière fonctionne tres bien:
    Mais que déclarée comme ceci non :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void affiche();
    Les éléments ne sont pas détruits avant la fin du thread. Et même si ils l'étaient, l'élément ne serait simplement plus appelé dans la boucle principale du thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (ptrMWidget = mWidget.begin(); ptrMWidget != mWidget.end(); ++ptrMWidget)
    {
            ptrMWidget->second->affiche(); //C'est ici que survient l'érreur de segmentation lorsque la fonction affiche est virtuelle.
    }
    Encore une fois merci, car tant que ceci n'est pas éclairci je ne peu pas continuer mon projet .

  6. #6
    Futur Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 7
    Points : 5
    Points
    5
    Par défaut
    Humm
    Veuillez m'escuser mais le problème est tout autre ^^.
    Il survenait à une autre partie du programme.
    Je vous ais orienté sur une mauvaise piste et c'est entièrement de ma faute (il faudrai que j'aprenne à me servir d'un outil de débogage ).

    Le problème survenait ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Bouton * objetBouton;
    objetBouton = new Bouton;
    addWidget(objetBouton, "coucou", 0);
    addWidget(objetBouton, "Salut", 0);
    addWidget(objetBouton, "Hello", 0);
    removeWidget("Salut", 0);
    et plus éxactement là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    bool Ecran::removeWidget(std::string nomWidget, int couche)
    {
        if( couche < vCouches.size() )
        {
            mWidgets objMWidget;
            objMWidget = vCouches[couche];
            if(objMWidget.find(nomWidget) != objMWidget.end())
            {
                delete objMWidget[nomWidget];
                objMWidget.erase(nomWidget);
                vCouches[couche] = objMWidget;
                return true;
            }
            return false;
        }
        return false;
    }
    Comme quoi on travaile quelque fois mieu à 3h du mat qu'en plein aprem ^^.
    Et c'était mon protocole de test qui était completement foireu.
    Car je créait un seul et unique objet Bouton, qui était ensuite rangé plusieur fois dans mon tableau. Mais lorsque je suprimait un Bouton, je détruisait aussi l'objet qui lui était associé (sinon sa fait des fuites mémoires ^^).
    Donc ensuite j'avais plusieurs pointeurs dans ma map qui pointaient vers un objet qui n'éxiste plus (Comme l'as remarqué Fiquet).
    Du coup j'ai reprit mon protocole de test apres avoir "trop" précipitement répondu sur votre forum.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Bouton * objetBouton;
    objetBouton = new Bouton;
    addWidget(objetBouton, "coucou", 0);
    objetBouton = new Bouton;
    addWidget(objetBouton, "Salut", 0);
    objetBouton = new Bouton;
    addWidget(objetBouton, "Hello", 0);
    removeWidget("Salut", 0);
    Et là tout fonctionne .

    En tout cas j'aimerai beaucoup que l'on m'explique pourquoi sa fonctionnait lorsque la donnée membre affiche n'était pas virtuelle 'cela m'as beaucoup induit en érreur).

    Et encore une fois désolé , et surtout merci !

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En tout cas j'aimerai beaucoup que l'on m'explique pourquoi sa fonctionnait lorsque la donnée membre affiche n'était pas virtuelle 'cela m'as beaucoup induit en érreur).
    La joie des comportements aléatoires...

    Le fait que le destructeur de Widget ne soit pas virtuel alors qu'il devrait l'être n'a sans doute pas arrangé les choses.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Héritage virtuel et constructeur.
    Par Klaim dans le forum C++
    Réponses: 17
    Dernier message: 10/01/2015, 21h18
  2. Question sur l'héritage virtuel
    Par ezsoft dans le forum C++
    Réponses: 10
    Dernier message: 20/08/2008, 09h13
  3. template, héritage virtuel: gcc vs Visual II
    Par 3DArchi dans le forum Langage
    Réponses: 5
    Dernier message: 07/08/2008, 15h53
  4. Création d'un écran virtuel sous SDL
    Par sieuzac dans le forum SDL
    Réponses: 9
    Dernier message: 02/06/2007, 12h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo