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

 C++ Discussion :

Pointeur sur une fonction membre


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 46
    Points : 26
    Points
    26
    Par défaut Pointeur sur une fonction membre
    Bonjour,

    Est il possible qu'un pointeur membre d'une instance de classe "A" pointe vers une fonction membre d'une instance de classe "B", sachant que la classe "B" est une classe dérivée de "A"?
    Si oui comment faire? Car je n'y arrive pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class A
    {
    void (*_fUpdate)(void);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class B: class A
    {
    void Update(void);
    }
    et j'aimerai pouvoir écrire
    sans que le compilateur m'insulte, du genre:
    error C2440: '='*: impossible de convertir de 'void (__thiscall B::* )(void)' en 'void (__cdecl *)(void)'

    Merci pour votre aide.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Non, parce que le pointeur sera appelé avec des valeurs de n'importe quel type compatible avec A (la base), pour lesquelles, la fonction n'existe pas.

    Par exemple, le pointeur peut contenir un A, ou encore un C (public A, mais pas B).


    Cela dit, cette réponse est pour une autre question...


    La réponse est plutot:
    B::update est une fonction liée à une instance (une méthode), ce n'est pas une fonction libre.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Salut,

    L'intérêt d'avoir une classe de base et des classes filles qui en héritent, c'est essentiellement d'avoir dans la classe mère les fonctionnalités qui sont communes à toutes les classes filles. D'un point de vue conceptuel, il n'y a donc un intérêt de faire ce que tu cherches à faire que s'il y a une erreur de conception. Du point de vue du langage, il n'est pas possible pour ta classe mère de connaitre ses classes filles.

    Maintenant, concernant ton besoin, je ne vois pas quel est l'intéret pour toi de procéder ainsi. Ce que tu peux donc faire :

    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
     
    struct A
    {
        virtual void update() =0; //pure virtual method => must be implemented in all subclasses of A..
    }
     
    struct B: public A
    {
       void update()
       {
          //specific update method for B classes..
       }
    }
     
    struc C: public A
    {
       void update()
       {
           //specific update method for C classes..
       }
    }
    Bon je n'ai pas fait de C++ depuis très longtemps, pas dit que le code soit correct, mais normalement l'explication l'est ^^

    Bon courage
    Nullius in verba

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Ton code est bon aussi (même si j'ai tendance à préférer expliciter les public:, et les commentaires en français).

    @pingouin84k: Il nous faut plus de conseil pour te donner une réponse adaptée au besoin.
    En général, les pointeurs de fonctions membres ne sont pas nécessaires.
    Il suffit de manipuler les objets via des références ou pointeurs
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Merci à vous deux de m'avoir répondu! Voilà plus de détail de ce que j'essaie de faire.

    J'ai une classe qui représente un objet mathématique (un scalaire, un vecteur, une matrice, etc) dont les opérations arithmétiques sont déjà définies (j'ai overloadé les opérateurs et les fonctions mathématiques usuelles). Les valeurs des composantes de l'objet mathématique sont contenues dans un tableau de valeurs. Et a chaque fois qu'une fonction essaie d'accéder à ses valeurs, j'ai besoin de les mettre à jour par une fonction externe qui diffère d'une instance à l'autre.

    Ma classe fille dérive de la dernière car je rattache d'autres données à ses objets mathématique (par un exemple un nom de variable, ou les dérivées). Par ailleurs c'est à la classe dérivée que je souhaite faire appel pour mettre à jour les valeurs. J'utilise un héritage, car à ce stade, je n'ai pas vraiment envie de me retaper toute les surcharges d'opérateur et de fonctions mathématiques (car la solution pourrait être de déclarer la classe de base comme membre de la classe dérivée).

    J'ignore si c'est assez clair...

  6. #6
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Citation Envoyé par pingouin84k Voir le message
    j'ai besoin de les mettre à jour par une fonction externe qui diffère d'une instance à l'autre.
    Si tu as une fonction qui diffère d'une instance à l'autre, soit tu essaies d'associer à une même famille des objets qui n'en font pas partie, soit au contraire tu ne spécialise pas suffisamment tes objets. Il s'agit donc d'une faiblesse dans ta conception.

    Sache également que, même si c'est déroutant au départ, une notion d'héritage dans le domaine des mathématiques ne s'applique pas forcément dans le domaine de la programmation. Par exemple, un carré est un rectangle mathématiquement, mais ceci n'est pas vrai en programmation, car ce la brise le principe de substitution de Liskov, principe SOLID devant être respecté pour garantir la bonne conception de ton programme.
    Nullius in verba

  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Sans forcément entrer dans tous les détails, tu peux nous montrer deux classes de tes objets, et la fameuse fonction qui diffère?

    Par exemple math::vector et math::matrix (en supposant que math soit ton namespace... tu en as bien un, n'est-ce pas? )

    Au passage, puisque tu parles de matrices, tu as bien lu nos deux entrées dans la faq à leur sujet?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  8. #8
    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
    Normalement c'est à ça que sert virtual et le polymorphisme.

    Sinon, ton problème est plutôt clair : Update est un membre de B, et toi tu veux stocker une fonction libre.
    Les fonctions membres et non membres n'ont rien à voir et pas la même syntaxe de foncteur.
    Sinon, tu peux faire comme indiqué ici http://www.developpez.net/forums/d14...e/#post8106791
    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.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    J'aurai peut être dû le préciser, mais je suis pas très à l'aise en C++.
    Disons que j'ai commencé le C++ il y a quelques semaines, sur le tas.

    Mon but est de faire un code de CFD plus rapide que celui que j'ai pondu en thèse en Matlab.
    Donc on peut pas dire que je m'attaque à un programme des plus facile. Et parfois je patauge dans les arcane du langage.

    @Kaamui
    Je veux jouer avec les règles du jeux que l'on enseigne dans les livres, mais je l'ai connais absolument pas. Donc les phrases du type
    car ce la brise le principe de substitution de Liskov, principe SOLID devant être respecté pour garantir la bonne conception de ton programme.
    ne m'aide pas vraiment. Et pour avoir recherché quelques minutes ce que sont ces principes, je ne suis même pas convaincu que cela soit nécessaire dans mon cas... Mon but n'étant pas de faire un programme pour la NASA (quoique...)!

    Cela dit, j'ai essayé de passer par une fonction virtuelle et les premiers tests semblent répondre à mon besoin. Même mieux que ce que j'espérai. Donc merci Kaamui.


    @leternel
    Voici un extrait de la classe qui me sert d'objet mathématique générique (modifié après les conseils de Kaamui).

    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
    class Quantity
    {
    public:
    	// constructeurs
    	Quantity(void);
     
    [...]
     
    protected:
    	unsigned short _dimV; // dimension de l'objet mathématique
    	unsigned short _dimH; // dimension de l'objet mathématique
    	float* _val; // valeur des composantes de l'objet mathématique
     
    	//void (*_fUpdate)(void); // pointeur vers la fonction qui met à jour les valeurs
    	virtual void Update(void);
    };
    Puis dans la classe dérivée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Variable : public Quantity
    {
    [...]
    	void Update(void);
    }
    A l'initialisation d'une instance de cette dernière classe j’essayais de faire pointer _fUpdate vers Update().

    Et non je n'ai rien lu sur math::vector et math::matrix. Mes premiers essais avec vector m'ont montré que c'était beaucoup plus lent que d'utiliser tableau. Du coup je les utilise pas.

  10. #10
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    alors math:: c'était une suggestion de nom pour le namespace que tu devrais définir.

    Par ailleurs, un std::vector est un tableau. C'est aussi rapide, surtout quand tu sais quelle taille il doit faire.

    Dans ton cas, je ne suis pas sur qu'une variable soit une quantité. Ca en contient une, peut-être.
    Ca va te prendre un peu de temps, mais il faudrait, je pense, que tu t'intéresse aux template.

    Enfin, un gros conseil: si tu n'es pas à l'aise avec le C++, commence par des programmes jouets, qui te feront prendre le langage en main.
    Par exemple, réimplémenter des outils linux comme cat, less, tee, ls, ou encore des jeux simples comme un pendu ou un plus-ou-moins.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  11. #11
    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
    Si tu débutes, et si tu veux des perfs n'essaye pas de faire ta classe de matrices toi même, ce n'est pas si simple que l'on peut croire, surtout si on veut tirer parti à 100% de la puissance de la machine. Il existe des classes qu'on peut trouver à droite à gauche (nt², eigen, probablement d'autres, je ne peux pas t'aider à choisir, ça fait longtemps que je n'ai pas fait d'info scientifique, peut-être en regardant là http://stackoverflow.com/questions/1...ra-libraries-a ?)
    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.

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Merci à vous tous pour vos conseils.
    JolyLoic tu m'avais déjà conseillé de regarder la dedans quand j'étais au début du début.

    Personnellement, j'aime (et ça ne me gène pas) de mettre les mains dans le cambouis (quitte à réinventer la roue).
    Mais ce qui m'a décidé à utiliser des tableaux déclarés par moi-même et pas des vecteurs (et en dépits que je reconnais que la classe vector est beaucoup beaucoup plus simple à utiliser) c'est le benchmark qui m'indique que l'utilisation du vector est 40 fois plus lent...


    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
    46
    47
    48
    49
    50
    51
     
    #include <vector>
    #include "time.h"
    using namespace std;
     
     
    int main()
    {
    	unsigned int n = 5000000;
    	vector<float> v1(n);
    	vector<float> v2(n);
    	vector<float> v3(n);
     
     
    	for (unsigned int i = 0; i < n; i++)
    	{
    		v1[i] = (float)rand();
    		v2[i] = (float)rand();
    	}
     
    	clock_t debut = clock();
    	for (unsigned int i = 0; i < n; i++)
    	{
    		v3[i] = v1[i] + v2[i];
    	}
    	clock_t duree = clock() - debut;
    	printf("%f\n", static_cast <double> (duree) / CLOCKS_PER_SEC);
     
     
    	float* f1 = new float[n];
    	float* f2 = new float[n];
    	float* f3 = new float[n];
     
    	for (unsigned int i = 0; i < n; i++)
    	{
    		f1[i] = (float)rand();
    		f2[i] = (float)rand();
    	}
     
    	debut = clock();
    	for (unsigned int i = 0; i < n; i++)
    	{
    		f3[i] = f1[i] + f2[i];
    	}
    	duree = clock() - debut;
    	printf("%f\n", static_cast <double> (duree) / CLOCKS_PER_SEC);
     
     
     
    	return 0;
    }

    Les fonctions virtuelles feront l'affaire pour mon besoin. Je passe le sujet en Resolu.

  13. #13
    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
    Citation Envoyé par pingouin84k Voir le message
    Merci à vous tous pour vos conseils.
    JolyLoic tu m'avais déjà conseillé de regarder la dedans quand j'étais au début du début.

    Personnellement, j'aime (et ça ne me gène pas) de mettre les mains dans le cambouis (quitte à réinventer la roue).
    Alors, bon courage, et mets toi bien les mains dans le camboui (entre autres) des expression templates et des primitives de vectorisation de ton processeur.
    Citation Envoyé par pingouin84k Voir le message
    Mais ce qui m'a décidé à utiliser des tableaux déclarés par moi-même et pas des vecteurs (et en dépits que je reconnais que la classe vector est beaucoup beaucoup plus simple à utiliser) c'est le benchmark qui m'indique que l'utilisation du vector est 40 fois plus lent...
    Je viens de tester ton code avec mon compilateur, et j'obtiens :
    Ce qui signifie que le code pour vector est significativement plus rapide que pour des tableaux... Je l'ai exécuté plusieurs fois, la tendance était constante.
    Tu es certain d'avoir fait tes tests en mode optimisé ?
    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.

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Je viens de tester ton code avec mon compilateur, et j'obtiens :
    Ce qui signifie que le code pour vector est significativement plus rapide que pour des tableaux... Je l'ai exécuté plusieurs fois, la tendance était constante.
    Tu es certain d'avoir fait tes tests en mode optimisé ?
    J'obtiens l'inverse de ton résultat.
    Tu me conseilles de regarder à quel endroit pour optimiser ce bout de code (très sincèrement je serai ravi de travailler avec des vecteurs).

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    j'ai fait les tests en Debug et pas en Release..........................
    Et maintenant j'obtiens le même résultat que toi. D'autres conseils pour optimiser la vitesse d’exécution?

  16. #16
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Je te recommande l'usage de l'équivalent pour ton compilateur de l'option -O2 (voire -O3) de gcc

    En règle général, les conteneurs de la stl sont puissants (tant que tu ne les mélange pas comme un vector<vector>)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    D'autres conseils pour optimiser la vitesse d’exécution?
    Ne pas réinventer la roue.
    On fera toujours une roue voilée.

    Sinon, on n'optimise que du code pleinement fonctionnel et en se basant sur les résultats d'un profiler, pas au doigt mouillé.

  18. #18
    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,
    Citation Envoyé par pingouin84k Voir le message
    @Kaamui
    Je veux jouer avec les règles du jeux que l'on enseigne dans les livres, mais je l'ai connais absolument pas. Donc les phrases du type ne m'aide pas vraiment. Et pour avoir recherché quelques minutes ce que sont ces principes, je ne suis même pas convaincu que cela soit nécessaire dans mon cas... Mon but n'étant pas de faire un programme pour la NASA (quoique...)!
    car ce la brise le principe de substitution de Liskov, principe SOLID devant être respecté pour garantir la bonne conception de ton programme.
    Au risque de passer pour un maudit spammeur qui fait sa pub sur le forum, il se fait que j'ai écrit un livre sur les bonnes pratique et les erreurs à éviter lorsque l'on veut développer en C++ et que ce livre s'intéresse justement en profondeur aux principes SOLID (entre autres)... Tu trouveras le lien vers ce livre dans ma signature

    Ceci dit, si tu recherche les termes SOLID ou LSP sur ce forum, tu trouveras plein d'interventions qui traitent de ces principes
    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

  19. #19
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Et ce ne sont pas du tout des principes réservé à la NASA ou qui ne sont utiles que sur des programmes gigantesques. Ce sont des fondamentales. Pour simplifier (mais je compte sur les autres membres pour préciser ma tentative risquée) ) :

    Comment concevoir : Classe de service vs classe de données : est-ce que je penses mes classes comme des contenants, ou comme des services (personnellement je trouve qu'on ne devrait pas coder autrement qu'en classe de service, même si ce n'est pas la manière la plus instinctive au départ, car la flexibilité est bien meilleure et le concept se marie vraiment bien avec l'héritage multiple du C++)

    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    //classe de données : car on la conçoit comme suit : "un Character POSSEDE UN sprite, POSSEDE UNE position. un Boss EST UN Character, un Hero EST UN Character"
    public class Character
    {
       Sprite sp;
       Position pos; 
     
    public :
       void draw();
       void move();        
    }
     
    public class Hero : public Character
    {
       public:
          void protectThePrincess();
    }
     
    public class Boss : public Character
    {
       public: 
          void attackThePrincess();
    }
     
     
    //classe de service: un Character EST DESSINABLE, DEPLACABLE. Un Boss EST UN Character, un Hero EST UN Character
    public class Drawable
    {
       Sprite sp;
     
    public :
       void draw();
    }
     
    public class Movable
    {
       Position pos;
     
    public :
       void move();
    }
     
    public Character : Drawable, Movable
    {
     
    }
     
    public class Hero : public Character
    {
       public:
          void protectThePrincess();
    }
     
    public class Boss : public Character
    {
       public: 
          void attackThePrincess();
    }
    L'encapsulation : protège toi d'une modification lourde dans tout ton programme par l'encapsulation :
    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
     
    //ton code...
    public class Drawable
    {
       public:
           Sprite sp; //ainsi, tu accède partout à sp sans passer par une fonction qui est plus longue à écrire... 
    }
    //le mien...
    public class Drawable
    {
       Sprite sp;
       public :
          void draw() { sp.draw(); };
    }
    //imaginons maintenant que nous avons 25000 lignes de codes et 600 occurrences de sp.draw() dans nos codes et de la méthode draw()  dans nos codes respectifs, et qu'on veuille ajouter une condition avant de dessiner notre objet.. qui va le plus vite à modifier son code ? ^^
    Quelle est la nature de mon objet : Sémantique de valeur vs sémantique d'entité : tous les objets peuvent se concevoir des deux façons il n'y a pas de mauvaise réponse, juste une réponse adaptée à un besoin. Par exemple, une pièce de 1€ et une autre pièce de 1€ peuvent être schématisées par une classe à sémantique de valeur (le premier objet = le second) dans un logiciel de comptabilité, mais avoir une sémantique d'entité (le premier objet != du second) si tu programmes un univers par exemple ^^. Cela a un impact direct sur les opérateurs de comparaison liés à ta classe, entre autres.

    S: Single Responsibility Principle : une classe ou une méthode doit avoir une tache unique. Dans l'exemple précédent, la classe Drawable n'a qu'une seule responsabilité, celle de rendre le service "Dessine moi" à un objet.
    O: Open-Closed Principle : une classe doit être ouverte à l'extension, pas à la modification. En respectant les autres principes, tu verras que celui-ci se met généralement en place très naturellement. Par exemple la classe Character : j'aurais très bien pu mettre un bool isHero dans ma classe Character, et puis la mettre à faux quand il j'instancie un Boss, vrai sinon. Mais en faisant cela, je m'ouvre à un tas de complications, dans le futur, que tu as dû cerner au moment où tu lis, Alors qu'en procédant ainsi, si demain je souhaite ajouter 6 type de Characters supplémentaires, je n'ai aucune difficulté à le faire.
    L: Liskov Substition Principle: reprends les explications sur mon premier post concernant les objets mathématique et leur traduction en langage de programmation. En respectant ce principe, on s'assure que notre architecture de classes est solide. Réalise pour t'en convaincre une architecture où tu fait hériter d'une classe Rectangle une classe Carré, et joue un peu avec pour te rendre compte des impasses que cela créé..
    I: Interface Segregation Principle: la phrase dans le wiki résume très bien la chose : "many client-specific interfaces are better than one general-purpose interface". (Imagine les implications pour le code d'avoir une interface qui gère 300 types d'utilisateurs, plutôt que d'avoir 300 interfaces qui gèrent un type d'utilisateur).
    D: Dependency Inversion Principle: encore une fois wiki : one should "Depend upon Abstractions. Do not depend upon concretions.". En ajoutant un niveau d'abstraction au niveau des dépendances de ton projet, tu évites de lourds problèmes en cas de changement majeur dans la direction de ton projet. Imaginons que tu utilises Boost pour ton projet. 3 mois plus tard, tu te rend compte qu'une bibliothèque beaucoup plus légère répond exactement à ton besoin, contrairement à Boost qui répond à beaucoup plus. Si tu as rendu paramétrable cette utilisation de Boost via tes abstractions, alors tu passe de Boost à une nouvelle bibliothèque très facilement. Si tu n'as pas fait cela, tu abandonnes car cela voudrait dire refaire 3 mois de travail pour changer de biblio, et tanpis si l'autre était mieux...




    Enfin, fais attention : il existe plusieurs écoles dans la programmation. Tous les conseils que tu reçois ne se valent pas. Cependant tout le monde (ou presque) s'accordera à dire sur ce forum qu'il y a des personnes que tu peux écouter sans trop de craintes : Koala01, JolyLoic, Flob90 etc... désolé pour ceux que j'oublie ça fait longtemps que je ne passe plus ^^
    Nullius in verba

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

Discussions similaires

  1. Pointeur sur une fonction membre templatée et +
    Par metagoto dans le forum Langage
    Réponses: 2
    Dernier message: 09/08/2013, 02h05
  2. Réponses: 5
    Dernier message: 29/06/2006, 17h23
  3. Réponses: 3
    Dernier message: 16/05/2006, 18h22
  4. Pointeur sur des fonctions membres d'une classe
    Par Muetdhiver dans le forum C++
    Réponses: 3
    Dernier message: 15/02/2006, 11h35
  5. Probleme de pointeur sur une fonction
    Par nicky78 dans le forum C
    Réponses: 2
    Dernier message: 23/05/2004, 20h26

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