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 :

Executer méthode de classe Fille dans classe Mère via un pointeur sur méthode


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 51
    Par défaut Executer méthode de classe Fille dans classe Mère via un pointeur sur méthode
    Bonjour,

    Afin de régler un problème d'affichage dans le cadre d'un exercice de programmation parallèle, je bute sur un problème : dans ma classe A, je veux une méthode, qui me permette d'executer la méthode passée en paramètre (avec des instructions en plus). Dans ma classe B, qui hérite de ma classe A, je veux pouvoir appeler cette méthode de A, dans B, avec comme paramètre un pointeur sur une méthode de B.

    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
     
    class A {
        void virtual routine() {}
        void executer(void (*function)(int), int param) {
            instruction();
            (*function)(param);
            instruction();
        }
    };
     
    class B : A {
        void routine() {
            executer(&ma_fct, 2);
        }
        void ma_fct(int p) {
            cout << p << endl;
        }
    };
    Mais je ne parviens pas à faire fonctionner ce code... Il est évidamment faux ici, j'ai commencé par utiliser (*A::function) dans la déclaration présente dans A, mais du coup je me retrouve avec &B::ma_fct comme paramètre de executer() dans la classe B...

    Vous auriez une idée pour résoudre ce problème ?

    Bonne journée !

  2. #2
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Plusieurs solutions : std::function, ou pointeur de fonction + cast.
    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
    42
    43
    #include <iostream>
    #include <functional>
     
    class A {
    public:
    	void virtual routine() {}
    	void executer(std::function<void(int)> fct, int param) {
    		fct(param);
    	}
     
    	void executer2(std::function<void(void)> fct) {
    		fct();
    	}
     
    	template <class T>
    	void executer3(void (T::*fct)(int), int param) {
    		static_assert(std::is_base_of<A, T>::value, "nop.png");
    		(static_cast<T*>(this)->*fct)(param);
    	}
    };
     
    class B : public A {
    public:
    	void routine() {
    		executer([this](int i) { ma_fct(i); }, 1);
    		executer(std::bind(&B::ma_fct, this, std::placeholders::_1), 2);
     
    		executer2(std::bind(&B::ma_fct, this, 3));
     
    		executer3(&B::ma_fct, 4);
    	} 
     
    	void ma_fct(int p) {
    		std::cout << p << std::endl;
    	}
    };
     
    int main() {
    	B b;
    	b.routine();
     
    	return 0;
    }

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Et pourquoi pas du CRTP ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 51
    Par défaut
    Merci pour ton aide Iradrille ! Ca marche nickel !

    Bousk : Pourrais tu être plus précis concernant ton idée ?

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    As-tu besoin que ma_fct soit non statique ? C'est ça qui cause ton soucis et qu'Iradrille essaye de corriger à coup de bind.

    Sinon, de nos jours, je trouve un lambda plus clair et générique qu'un bind :

    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
    class A {
        void virtual routine() {}
        void executer(std::function<void(int)> f, int param) {
            instruction();
            f(param);
            instruction();
        }
    };
     
    class B : A {
        void routine() {
            executer([this](int param){this->ma_fct(param);} , 2);
        }
        void ma_fct(int p) {
            cout << p << endl;
        }
    };
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut
    Un mois après, j'apporte mon grain de sel (si quelqu'un suit encore ce fil) :
    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
    42
    43
    44
    45
    #include <iostream>
    using namespace std ;
     
    struct A
        {
        typedef void (A::*t_fct) ( int ) ;
        virtual void ma_fct1 ( int ) = 0 ;
        virtual void ma_fct2 ( int ) = 0 ;
        virtual void ma_fct3 ( int p )
            {
            cout << "A::ma_fct3(" << p << ")" << endl ;
            }
        void executer ( t_fct func, int param )
            {
            (this->*func)( param ) ;
            }
        };
     
    struct B : A
        {
        void ma_fct1 ( int p )
            {
            cout << "B::ma_fct1(" << p << ")" << endl ;
            }
        void ma_fct2 ( int p )
            {
            cout << "B::ma_fct2(" << p << ")" << endl ;
            }
        void ma_fct4 ( int p )
            {
            cout << "B::ma_fct4(" << p << ")" << endl ;
            }
        void routine ()
            {
            executer( &A::ma_fct1,2 ) ;
            executer( &A::ma_fct2,3 ) ;
            executer( ma_fct3,4 ) ;
         // executer( &A::ma_fct4,3 ) ; // error: 'ma_fct4' is not a member of 'A'
            }
        };
    int main ()
        {
        B b ;
        b.routine() ;
        }
    La sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    B::ma_fct1(2)
    B::ma_fct2(3)
    A::ma_fct3(4)
    Voilà, pas besoin de template, ni de cast, ni d'aucune version récente de c++...
    La seule ombre : je ne m'explique pas la nécessité d'ajouter &A:: devant ma_fct1 et ma_fct2.

Discussions similaires

  1. Réponses: 1
    Dernier message: 20/09/2013, 10h02
  2. Appel méthode classe fille, dont classe mère virtuelle
    Par Metalman dans le forum Débuter
    Réponses: 6
    Dernier message: 07/06/2013, 11h51
  3. Réponses: 4
    Dernier message: 14/12/2011, 15h58
  4. Réponses: 6
    Dernier message: 22/07/2010, 15h17
  5. Réponses: 21
    Dernier message: 22/10/2007, 10h10

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