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

Langage C++ Discussion :

[Boost.bind] binder method d'une classe derivée depuis la base


Sujet :

Langage C++

  1. #1
    Membre averti Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Points : 437
    Points
    437
    Par défaut [Boost.bind] binder method d'une classe derivée depuis la base
    Bonjour Tout le monde,

    j'ai un problem que je n'arrive pas a resoudre, je voudrai appeler la methode "overrided" de la classe derivée depuis la classe de base :

    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
    class Base{
    	public: 
    		void start(){
    			new thread(boost::bind(&Base::run, this));
    		}
     
    		void go(){
    			// do something
    		}
     
    }
     
     
    class Derived : public Base {
    	public:
    		void go(){
    			//do something different
    		}
    }
     
     
    int main(int argc, char** argv){
    	Derived* der = new Derived();
    	der->start();
     
    	return 0;
    }
    dans ce code j'obtient toujour le go() de la classe Base, ce que je veux c'est avoir le run() de la classe Derived, est-ce que c'est possible ?

    apparement c'est le boost bind qui pose probleme, vue que je lui passe Base::run en argument,

    merci d'avance pour votre aide.

    Cdlt

  2. #2
    Membre averti Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Points : 437
    Points
    437
    Par défaut
    en fait je ne pense pas que le problème vient de boost::bind, j'ai essayé ce code :
    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
    28
    29
    30
    31
    class Base{
    	public: 
    		void start(){
    			new thread(boost::ref(*this));
    		}
     
    		void go(){
    			//do something.
    		}
     
    		void operator()(){
    			this->run();
    		}
     
    }
     
     
    class Derived : public Base {
    	public:
    		void go(){
    			//do something different
    		}
    }
     
     
    int main(int argc, char** argv){
    	Derived* der = new Derived();
    	der->start();
     
    	return 0;
    }
    et ça ne marche toujours pas !!

    une idée ?

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 369
    Points
    50 369
    Par défaut
    Et si tu essayais en mettant virtual devant void go(). C'est justement à cela que ca sert !!

    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
    class Base{
    	public: 
    		void start(){
    			new thread(boost::ref(*this));
    		}
    		
    		virtual void go(){
    			//do something.
    		}
    		
    		void operator()(){
    			this->run();
    		}
     
    }
    
    class Derived : public Base {
    	public:
    		virtual void go(){ // ici, le virtual n'est pas obligatoire mais c'est plus cohérent
    			//do something different
    		}
    }

  4. #4
    Membre averti Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Points : 437
    Points
    437
    Par défaut
    salut ram-0000,

    desolé de ne pas l'avoir mentioné dans mes postes precedents, mais j'ai deja essayé avec le virtual, mais ça donne exactement le meme comportement !!

  5. #5
    Membre averti Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Points : 437
    Points
    437
    Par défaut
    salut tout le monde,

    le probleme a pris une autre tournure :
    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
    28
    29
    30
    31
    32
    class Base{
    	public: 
    		void start(){
    			new thread(boost::bind(&Base::go, this));
    		}
     
    		virtual void go(){
    			// do something
    		}
     
                    string print(){
                           return "something";
                    }
     
    }
     
     
    class Derived : public Base {
    	public:
    		void go(){
    			//do something different
    		}
    }
     
     
    int main(int argc, char** argv){
    	Derived* der = new Derived();
    	der->start();
            std::cout << der->print();
     
    	return 0;
    }
    comme ça marche comme prevu, mais si j'enleve std::cout << der->print(); du main, ça ne marche pas !!!

    des idées ?

  6. #6
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Le virtual est indispensable !!!
    Là tu triches. Il faut mettre Base* pour avoir le polymorphisme !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main(int argc, char** argv){
        Base* der = new Derived();
        der->start();
            std::cout << der->print();
     
        return 0;
    }
    Et là ça va plus marcher du tout !!!!

  7. #7
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    Comment ça pourrait ne serait-ce que compiler, il n'y aucune méthode run de déclarée ou définie nulle part...

    MAT.

  8. #8
    Membre averti Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Points : 437
    Points
    437
    Par défaut
    desolé c'est encore une erreur de frappe, je l'ai corrigé

    aprés quelques bricoles, j'ai trouvé le problème, il vient de l'utilisation de boost::thread, si je remplace cette ligne par un simple appel à go(), ça marche meme avec la premiere version (avec virtual bien sure)

    maintenant ce qui me tracasse, c'est pourquoi quand j'ajoute l'appel à print() dans le main() ça marche (meme en utilisant boost::thread) ? alors que la definition de la classe est la même !!!

  9. #9
    Membre averti Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Points : 302
    Points
    302
    Par défaut
    Chez moi le code fonctionne parfaitement...
    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
    28
    29
    30
    31
    32
    33
    34
    35
    #include <boost/thread.hpp>
    #include <boost/bind.hpp>
    #include <iostream>
     
    class Base{
        public: 
            void start(){
                boost::thread(boost::bind(&Base::go, this));
            }
     
            virtual void go(){
                std::cout<<"Base"<<std::endl;
            }
     
     
     
    };
     
     
    class Derived : public Base {
        public:
            void go(){
                std::cout<<"Derived"<<std::endl;
            }
    };
     
     
    int main(int argc, char** argv){
        Base* der = new Derived();
        der->start();
     
        std::system("pause");
     
        return 0;
    }

  10. #10
    Membre averti Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Points : 437
    Points
    437
    Par défaut
    salut tout le monde,

    merci vikki, tu m'as permis de voir d'ou vient le probleme, voici un code qui le reproduise :
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <boost/thread.hpp>
    #include <boost/bind.hpp>
    #include <iostream>
     
    class Base1{
        public:
     
            virtual ~Base1(){myThread->join();}
            void start(){
                myThread = new boost::thread(boost::bind(&Base1::go, this));
            }
     
            virtual void go(){
                std::cout<<"Base"<<std::endl;
            }
     
     
            boost::thread* myThread;
     
     
     
    };
     
     
    class Derived1 : public Base1 {
        public:
            void go(){
                std::cout<<"Derived"<<std::endl;
            }
    };
     
     
    int main(int argc, char** argv){
        Derived1* der = new Derived1();
        der->start();
     
        delete der;
        //der->myThread->join();
     
        return 0;
    }

    si vous commenter "delete der;" et uncommenter "der->myThread->join()" ça marchera,

    j'espere que quelqu'un pourra m'eclaircir

    merci d'avance

  11. #11
    Membre averti Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Points : 302
    Points
    302
    Par défaut
    Effectivement, le "delete der" provoque l'affichage "Base" et non "Derived". Sans être sûr, je peux tenter une explication. Le delete va successivement appeler le destructeur de Derived1 (qui ne fait rien) puis celui de Base1. Lors de la résolution de ~Base1(), où la fonction join() est utilisée, ton objet n'est plus considéré comme étant de type Derived1 puisque son destructeur a été appelé (tout ce qui faisait de lui un Dervied1 a déjà été détruit). L'objet est donc considéré comme étant de type Base1, et c'est son implémentation de go() qui est appelée.
    Après réflexion, ce comportement est indispensable, il empêche la manipulation d'objets membres de la classe fille dans le destructeur de la classe mère, où ces objets sont déjà détruits.

    EDIT: en fait la FAC répond à la question

  12. #12
    Membre averti Avatar de let_me_in
    Inscrit en
    Mai 2005
    Messages
    441
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 441
    Points : 437
    Points
    437
    Par défaut
    salut vikki,

    c'est effectivement ça ce qui se passe, c'est la meme reponse que j'ai eu dans un autre forum,

    merci tout le monde pour votre aide.

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 16/10/2005, 21h21
  2. [MFC]creer une classe derivé de CWinThread
    Par psyjess dans le forum MFC
    Réponses: 2
    Dernier message: 18/03/2005, 15h23
  3. Réponses: 38
    Dernier message: 16/02/2005, 03h03
  4. [C#][WebServices] Appel methode avec une classe en paramètre
    Par bran_noz dans le forum Windows Forms
    Réponses: 6
    Dernier message: 10/09/2004, 17h41
  5. [VB6]Enumérer les attributs et les méthodes d'une classe
    Par HPJ dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 04/05/2004, 19h34

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