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++

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 51
    Points : 55
    Points
    55
    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
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    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 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    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 du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 51
    Points : 55
    Points
    55
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    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 confirmé
    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
    Points : 455
    Points
    455
    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.
    Captain'Flam
    anciennement Sopsag, aka Hadrien
    Win seven x64 & Win 10 / Visual 2017 / Python 2.7 / Eclipse

  7. #7
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par Captain'Flam Voir le message
    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
    // executer( &A::ma_fct4,3 ) ; // error: 'ma_fct4' is not a member of 'A'
    Voilà, pas besoin de template, ni de cast, ni d'aucune version récente de c++...
    C'est pourtant ce qu'on cherche à faire : appeler une fonction de B depuis A, et non pas une fonction de A depuis B.

  8. #8
    Membre confirmé
    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
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    Argl ! J'y perds mon latin...

    C'est pourtant ce qu'on cherche à faire : appeler une fonction de B depuis A, et non pas une fonction de A depuis B.
    Il me semble que c'est ce que je fais : j'appelle la méthode B::ma_fct1 depuis la méthode A::executer.
    Le code qui ne compile pas avec l'appel à ma_fct4 serait aussi un appel d'une méthode de B depuis A sauf que la méthode n'est pas définie comme virtuelle dans A.

    Mais je pense comprendre que ce que tu voudrais, c'est ne pas avoir à déclarer ma_fct1 comme virtuelle pure de A.
    C'est à dire appeler depuis A une méthode de B que A ne connaîtrait pas du tout.

    Dans ce cas, en effet, le C++ "classique" ne peut plus rien...
    Si la méthode ma_fct1 n'est pas définie, au moins comme virtuelle pure, dans A, elle ne sera pas dans sa table des méthodes virtuelles, et A ne peut définitivement pas y accéder.
    Du coup, le fait que A hérite de B n'apporte plus rien (à part pour pouvoir appeler execute, ce qui n'est pas le problème).

    Au temps pour moi...
    Je continue à chercher...

    Hadrien
    Captain'Flam
    anciennement Sopsag, aka Hadrien
    Win seven x64 & Win 10 / Visual 2017 / Python 2.7 / Eclipse

  9. #9
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Hormis du CRTP comme j'avais proposé, on peut faire tout simple, std::function ou directement un pointeur de fonction.
    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
    #include <iostream>
    struct A {
    	template< class T, typename...Args >
    	void Exec(void(T::*fct)(Args...), T& obj, Args... args) {
    		(obj.*fct)(args...);
    	}
    	template< typename...Args >
    	void Exec(void(*fct)(Args...), Args... args) {
    		(*fct)(args...);
    	}
    };
    struct B {
    	void DoSomething() { std::cout << "working" << std::endl; }
    	void WithArgs(int a, char b) { std::cout << a << b << std::endl; }
    };
    void test(const char* t) { std::cout << t << std::endl; }
     
    int main() {
    	A a;
    	B b;
    	a.Exec(&B::DoSomething, b);
    	a.Exec(&B::WithArgs, b, 1, 'c');
    	a.Exec(&test, "toto");
    }
    Et voilà, tu peux appeler n'importe quelle méthode static ou de n'importe quel objet, avec les paramètres de ton choix.
    Testé sous VS2015.
    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.

  10. #10
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par Captain'Flam Voir le message
    Mais je pense comprendre que ce que tu voudrais, c'est ne pas avoir à déclarer ma_fct1 comme virtuelle pure de A.
    C'est à dire appeler depuis A une méthode de B que A ne connaîtrait pas du tout.
    C'est ça.

    @bousk, il y à moyen de forwarder les paramètres ?

    Ma tentative
    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
    #include <iostream>
     
    struct A {
    	template< class T, typename...Args >
    	void Exec(void(T::*fct)(Args...), T& obj, Args&&... args) {
    		(obj.*fct)(std::forward<Args&&>(args)...);
    	}
    };
    struct B {
    	void DoSomething() { std::cout << "working" << std::endl; }
    	void WithArgs3(int a, char b, char const* c) { std::cout << a << b << c << std::endl; }
    	void WithArgs2(int a, char b) { std::cout << a << b << std::endl; }
    	void WithArgs1(char const* c) { std::cout << c << std::endl; }
    };
     
    int main() {
    	A a;
    	B b;
    	a.Exec(&B::DoSomething, b);
    	a.Exec(&B::WithArgs3, b, 1, 'c', "d"); // ligne 20
    	a.Exec(&B::WithArgs2, b, 1, 'c');
    	a.Exec(&B::WithArgs1, b, "d"); // ligne 22
     
    	return 0;
    }
    Résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    1>  main.cpp
    1>main.cpp(20): error C2782: 'void A::Exec(void (__thiscall T::* )(Args...),T &,Args &&...)'*: paramètre modèle 'Args' ambigu
    1>  main.cpp(5): note: voir la déclaration de 'A::Exec'
    1>  main.cpp(20): note: est peut-être 'int, char, const char*'
    1>  main.cpp(20): note: ou       'int, char, const char(&)[2]'
    1>main.cpp(22): error C2782: 'void A::Exec(void (__thiscall T::* )(Args...),T &,Args &&...)'*: paramètre modèle 'Args' ambigu
    1>  main.cpp(5): note: voir la déclaration de 'A::Exec'
    1>  main.cpp(22): note: est peut-être 'const char*'
    1>  main.cpp(22): note: ou       'const char(&)[2]'
    Avec les deux versions. Même si cette version compilait, les paramètres ne seraient pas forwarder en présence d'un char const*, faudrait traiter les paramètres un par un (?)
    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
    #include <iostream>
     
    struct A {
    	template< class T, typename...Args >
    	void Exec(void(T::*fct)(Args...), T& obj, Args&&... args) {
    		(obj.*fct)(std::forward<Args&&>(args)...);
    	}
    	template< class T, typename...Args >
    	void Exec(void(T::*fct)(Args...), T& obj, Args... args) {
    		(obj.*fct)(args...);
    	}
    };
    struct B {
    	void DoSomething() { std::cout << "working" << std::endl; }
    	void WithArgs3(int a, char b, char const* c) { std::cout << a << b << c << std::endl; }
    	void WithArgs2(int a, char b) { std::cout << a << b << std::endl; }
    	void WithArgs1(char const* c) { std::cout << c << std::endl; }
    };
     
    int main() {
    	A a;
    	B b;
    	a.Exec(&B::DoSomething, b); // ligne 23
    	a.Exec(&B::WithArgs3, b, 1, 'c', "d");
    	a.Exec(&B::WithArgs2, b, 1, 'c'); // ligne 25
    	a.Exec(&B::WithArgs1, b, "d");
     
    	return 0;
    }
    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
    1>  main.cpp
    1>main.cpp(23): error C2668: 'A::Exec'*: appel ambigu à une fonction surchargée
    1>  main.cpp(9): note: est peut-être 'void A::Exec<B,>(void (__thiscall B::* )(void),T &)'
    1>          with
    1>          [
    1>              T=B
    1>          ]
    1>  main.cpp(5): note: ou       'void A::Exec<B,>(void (__thiscall B::* )(void),T &)'
    1>          with
    1>          [
    1>              T=B
    1>          ]
    1>  main.cpp(23): note: lors de la tentative de mise en correspondance de la liste des arguments '(void (__thiscall B::* )(void), B)'
    1>main.cpp(25): error C2668: 'A::Exec'*: appel ambigu à une fonction surchargée
    1>  main.cpp(9): note: est peut-être 'void A::Exec<B,int,char>(void (__thiscall B::* )(int,char),T &,int,char)'
    1>          with
    1>          [
    1>              T=B
    1>          ]
    1>  main.cpp(5): note: ou       'void A::Exec<B,int,char>(void (__thiscall B::* )(int,char),T &,int &&,char &&)'
    1>          with
    1>          [
    1>              T=B
    1>          ]
    1>  main.cpp(25): note: lors de la tentative de mise en correspondance de la liste des arguments '(void (__thiscall B::* )(int,char), B, int, char)'
    Sinon un CRTP est une bonne solution tant qu'on ne manipule pas la classe de base directement (pas de fonctions virtuelles).

  11. #11
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    void Exec(void(T::*fct)(typename std::remove_reference<Args>::type...), T& obj, Args&&... args).
    Ce qui empêche toutes références en paramètre.

    Le plus simple reste d'utiliser std::invoke ou de templater les types de la fonction:
    template<class T, class.. FnArgs, class... Args> void Exec(void(T::*fct)(FnArgs...), T& obj, Args&&... args).

    (note: Exec ne prend pas en compte les méthodes const)

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    De manière générale, tu ne veux pas vraiment avoir à faire cela : La connaissance du contenu des classe va des classes dérivés qui connaissent le contenu de la classe parent et non l'inverse, ce qui fait que, si tu as "été assez bête" pour "perdre le type réel de ton objet" (comprend : connaitre ton objet de type dérivé comme étant un pointeur ou une référence sur le type de base) tu es condamné à ne connaitre que le type de base.

    Toute tentative de solution basée sur le transtypage (quel qu'il soit) ne fera que commencer à élever un mur dans lequel tu fonceras forcément à la première évolution de ton programme

    Cependant, il y a très certainement des solutions qui utilisent à peu près toutes les notions de double dispatch et / ou de polymorphisme :

    Par exemple, le patron de conception visiteur pourrait s'avérer utile, si le nombre de classes dérivées est "relativement restreint" et "particulièrement stable" (comprends : que tu n'est plus dans une phase dans laquelle tu risques d'ajouter trois classes dérivées par semaine)

    Sinon, une solution proche du patern NVI pourrait s'avérer viable : Soit la classe de base ressemblant à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Base{
    public:
       /* ... */
       void foo(/* parametres */)/* const */{
           /*test des préconditions */
          doIt(/* paramètres*/);
          /* test des post conditions */
       }
    private:
        virtual void doIt(/* paramètres */)/* const*/;
    }
    /* l'implémentation de doIt peut consister à ne rien faire ici ;) */
    la fonction doIt permettra d'apporter un "point de variation" dans ce qui est exécuté au niveau des classes dérivées, ainsi, si, en plus des paramètres que tu passes normalement à foo, ta classe dérivée a besoin d'autres paramètres il serait toujours possible de mettre en oeuvre une solution permettant à ta classe dérivée de connaitre ces paramètres avant l'appel à foo() (libre à toi de voir comment tu le feras ) qui te permettrait d'avoir une clase dérivée ressemblant à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Derivee : public Base{
    public:
       /* ... */
     
    private:
        void doIt(/* paramètres */)/* const*/ override
    }
    void Derivee::doIt(/* paramètres*/) /* const*/{
       /* tu peux utiliser "paramètres" ici et, si tu as eu l'occasion de "sauvegarer" les paramètres
        * supplémentaires nécessaires à une fonction, tu peux les récupérer et les utiliser ici ;)
        */
       bar(/*tout ce que tu veux qui pourrait être accessible au niveau de la classe dérivée */);
    }
    Et bien sur, il y a surement des solutions à plus longs termes (mais nécessitant sans doute une refonte bien plus importante), car, si tu as besoin, pour pouvoir utiliser ta classe dérivée, de paramètres (comprends : de données extérieures à ta classe dérivée) dont tu n'avais pas besoin au niveau de ta classe de base, il y a de fortes chances pour que quelques principes SOLID aient été quelque peu "égratignés" au niveau conceptuel. Si je devais faire un pronostique, je miserais le LSP en grand vainqueur et, pour obtenir le tiercé gagnant je rajouterais le DIP et le SRP.

    Sans oublier, bien sur, l'OCP, si tu décides de commencer à jouer avec des transtypages dans tous les sens
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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