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 :

Différentes créations de classes : héritage ou pas


Sujet :

C++

  1. #1
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut Différentes créations de classes : héritage ou pas
    Bonjour,

    voici une question que je me pose sur un projet actuel.
    Je dois créer deux classes variables : une classe "VariableInteger" et une classe "VariableDouble" qui doivent, outre contenir chacune leur attribut de la variable (int pour "VariableInteger" et double pour "VariableDouble"), aussi contenir un attribut du nom de la variable (std::string).

    Je pense à deux manières pour définir cela :

    1 : je crée une classe mère "Variable" ne contenant comme attribut que le nom de la variable, puis je crée les deux classes "VariableInteger" et "VariableDouble" qui héritent de la classe "Variable"
    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
     
    class Variable
    {
    	std::string m_name;
     
    	/* les méthodes qui vont bien */
    };
     
    class VariableInteger : public Variable
    {
    	int m_value;
     
    	/* les méthodes qui vont bien */
    };
     
    class VariableDouble : public Variable
    {
    	double m_value;
     
    	/* les méthodes qui vont bien */
    };
    2 : je crée uniquement les deux classes "VariableInteger" et "VariableDouble" qui ont chacune leur attribut de la variable (int pour "VariableInteger" et double pour "VariableDouble") ainsi que l'attribut supplémentaire du nom de la variable
    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 VariableInteger
    {
    	int m_value;
    	std::string m_name;
     
    	/* les méthodes qui vont bien */
    };
     
    class VariableDouble
    {
    	double m_value;
    	std::string m_name;
     
    	/* les méthodes qui vont bien */
    };
    Je ne vois pas spécifiquement la différence fondamentale (lors de l'exécution finale du logiciel créé) entre ces deux manières et je n'ai pas trouvé de réponse précise à cette question.

    Merci beaucoup.

  2. #2
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2009
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2009
    Messages : 391
    Points : 185
    Points
    185
    Par défaut
    Je ne suis pas expert mais je pense que si ta classe mère n'est pas plus développée que ça : il vaut mieux privilégier la seconde méthode.

    Corrigez moi les autres si je me trompe

  3. #3
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Certes la classe "Variable" ne contient que ce seul attribut du nom et les méthodes get et set qui vont bien.
    Mais qu'elle sera justement la différences ?

  4. #4
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    Utiliser l'héritage juste pour ça me parait compliqué. Tu es sûr que tu ne peux pas utiliser un template ?

  5. #5
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par phi1981 Voir le message
    Utiliser l'héritage juste pour ça me parait compliqué. Tu es sûr que tu ne peux pas utiliser un template ?
    Je peux utiliser ce que je veux.
    Néanmoins une petite explication sur la complication de l'utilisation (beaucoup de "ion" ) de l'héritage me serait utile.

  6. #6
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    Néanmoins une petite explication sur la complication de l'utilisation (beaucoup de "ion" ) de l'héritage me serait utile.
    Oh là je suis vraiment pas la personne la mieux indiquée, mais personnellement je préfère éviter l'héritage et plutôt favoriser la composition.
    Dans le cas de tes variables, l'idée d'avoir deux classes dérivées, une pour chaque type (si j'ai bien compris le but), est intéressante. Mais dans la pratique, à un moment, tu vas avoir un pointeur vers une "Variable", et même si tu sais que c'est un Int qu'elle contient, tu vas être bloqué parce qu'il te faudra faire un dynamic_cast ou un static_cast pour accéder à l'Int, ce qui est horrible.

  7. #7
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par phi1981 Voir le message
    Oh là je suis vraiment pas la personne la mieux indiquée, mais personnellement je préfère éviter l'héritage et plutôt favoriser la composition.
    Dans le cas de tes variables, l'idée d'avoir deux classes dérivées, une pour chaque type (si j'ai bien compris le but), est intéressante. Mais dans la pratique, à un moment, tu vas avoir un pointeur vers une "Variable", et même si tu sais que c'est un Int qu'elle contient, tu vas être bloqué parce qu'il te faudra faire un dynamic_cast ou un static_cast pour accéder à l'Int, ce qui est horrible.
    Merci beaucoup de ta réponse.

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Tes classes ont une sémantique de valeur, ce qui se marie mal avec l'héritage.

    En outre l'héritage public en C++ est de modéliser une relation EST-UN (i.e. un sous-typage) et doit respecter le LSP.
    Ce que tu essaies de faire ici, c'est de la réutilisation de code, ce qui passe plutôt par de la composition ou éventuellement un héritage privée [1].

    EDIT:
    1/ ou un template comme le fait fort justement remarqué Bousk

  9. #9
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    attention par défaut la visibilité d'un attribut ou méthode d'une classe est à private, donc ton héritage en plus ne fonctionnerait pas : VariableDouble ne peut pas accéder à son nom dans Variable dont il hériterait.

    Par contre, une solution très simple est selon moi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<class TYPE>
    class Variable
    {
     std::string m_name;
     TYPE m_value;
     ...
    }

  10. #10
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par gl Voir le message
    Tes classes ont une sémantique de valeur, ce qui se marie mal avec l'héritage.

    En outre l'héritage public en C++ est de modéliser une relation EST-UN (i.e. un sous-typage) et doit respecter le LSP.
    Ce que tu essaies de faire ici, c'est de la réutilisation de code, ce qui passe plutôt par de la composition ou éventuellement un héritage privée.
    Merci beaucoup pour ces précisions.
    Néanmoins je souhaite utiliser la classe variable comme identifiant de n'importe quelle variable (Integer ou Double ou autre) en créant par la suite des mécanismes pour que chaque variable est un identifiant unique.

    Citation Envoyé par Bousk Voir le message
    Bonjour,

    attention par défaut la visibilité d'un attribut ou méthode d'une classe est à private, donc ton héritage en plus ne fonctionnerait pas : VariableDouble ne peut pas accéder à son nom dans Variable dont il hériterait.

    Par contre, une solution très simple est selon moi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<class TYPE>
    class Variable
    {
     std::string m_name;
     TYPE m_value;
     ...
    }
    C'était une omision pour éviter d'alourdir le code, mais les attributs sont en protected.
    Je vais m'orienter vers cette solution.

    Merci beaucoup.

  11. #11
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Par contre si l'idée c'est d'avoir une collection de Variable indexées sur le nom indépendament du type.
    Je trouve l'idée pas top, parce que pour accéder à son type réel/valeur etc ça va être galère, et je pense que si vraiment on s'entête dans cette voie, il vaut mieux quelque chose comme ceci afin de pouvoir créer une collection
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Variable
    {
     std::string m_name;
     boost::any m_value; // voire variant, à vrai dire je ne les ai jamais utilisés
    };
    Et par mauvaise idée, j'entends que si à chaque manipulation il faut vérifier le type réel puis en récupérer la valeur correct selon son type, ça va être chiant pour l'utilisateur amha.

    D'ailleurs, en général quand un débutant vient en demandant de pouvoir créer une collection de n'importe quel type possible
    - structure
    - mauvaise conception
    - mauvaise habitude d'un autre langage
    - faux besoin ("au cas où")

  12. #12
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Par contre si l'idée c'est d'avoir une collection de Variable indexées sur le nom indépendament du type.
    Je trouve l'idée pas top, parce que pour accéder à son type réel/valeur etc ça va être galère, et je pense que si vraiment on s'entête dans cette voie, il vaut mieux quelque chose comme ceci afin de pouvoir créer une collection
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Variable
    {
     std::string m_name;
     boost::any m_value; // voire variant, à vrai dire je ne les ai jamais utilisés
    };
    Et par mauvaise idée, j'entends que si à chaque manipulation il faut vérifier le type réel puis en récupérer la valeur correct selon son type, ça va être chiant pour l'utilisateur amha.

    D'ailleurs, en général quand un débutant vient en demandant de pouvoir créer une collection de n'importe quel type possible
    - structure
    - mauvaise conception
    - mauvaise habitude d'un autre langage
    - faux besoin ("au cas où")
    Merci pour ces précisions, sauf que je ne peux utiliser boost (pour le moment).
    Pour mon besoin, j'ai un fichier ayant plusieurs variables données de la manière suivantes : Type nomVariable valeurVariable (où Type peut être int, double, bool et enum ; et nomVariable est un identifiant unique).
    À l'analyse de ce fichier, je crée des vecteurs de variables (un pour chaque Type) et par la suite j'accède à ces variables par leur nom.

  13. #13
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    J'avais fait ça, pour un problème similaire : https://github.com/Ekleog/misc/blob/.../namedvars.cpp

    Je ne sais pas si c'est exactement ce qui est recherché, mais ça m'en semble proche.

  14. #14
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Ekleog Voir le message
    J'avais fait ça, pour un problème similaire : https://github.com/Ekleog/misc/blob/.../namedvars.cpp

    Je ne sais pas si c'est exactement ce qui est recherché, mais ça m'en semble proche.
    Merci bien, je vais regarder.

  15. #15
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par MicBeastKiller Voir le message
    Merci pour ces précisions, sauf que je ne peux utiliser boost (pour le moment).
    Pour mon besoin, j'ai un fichier ayant plusieurs variables données de la manière suivantes : Type nomVariable valeurVariable (où Type peut être int, double, bool et enum ; et nomVariable est un identifiant unique).
    À l'analyse de ce fichier, je crée des vecteurs de variables (un pour chaque Type) et par la suite j'accède à ces variables par leur nom.
    Dans ce cas alors la première solution plus haut devrait convenir et tu auras une collection pour chaque type. Mais hors de question de mélanger les types !
    Je verrais bien ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template<class TYPE> class Variable
    {
      std::string m_name;
      TYPE m_value;
    };
    template<class TYPE> class Collection
    {
      std::vector<Variable<TYPE> > m_vector;
    };
    Ou bien utiliser directement une map<std::string, TYPE>

  16. #16
    Membre régulier
    Inscrit en
    Juin 2008
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 140
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Dans ce cas alors la première solution plus haut devrait convenir et tu auras une collection pour chaque type. Mais hors de question de mélanger les types !
    Je verrais bien ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template<class TYPE> class Variable
    {
      std::string m_name;
      TYPE m_value;
    };
    template<class TYPE> class Collection
    {
      std::vector<Variable<TYPE> > m_vector;
    };
    Ou bien utiliser directement une map<std::string, TYPE>
    C'est ce sur quoi je me suis dirigé. Je verrai plus tard pour le map<std::string, TYPE>.
    Merci beaucoup.

  17. #17
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    ou faire du Type erasure en ayant les classes templates qui heritent d'une classe non template fournissant l'interface qui va bien.

Discussions similaires

  1. Réponses: 8
    Dernier message: 13/11/2006, 16h45
  2. Erreur : La classe n'est pas enregistrée
    Par Le Pharaon dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 11/08/2005, 12h04
  3. héritage ou pas??
    Par neonico dans le forum C++
    Réponses: 1
    Dernier message: 24/11/2004, 10h51
  4. Erreur : La classe ne gère pas Automation..
    Par Invité dans le forum VBA Access
    Réponses: 1
    Dernier message: 09/09/2004, 10h24
  5. Réponses: 4
    Dernier message: 15/01/2004, 22h53

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