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 :

Héritage, polymorphisme, liste d'initialisation


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut Héritage, polymorphisme, liste d'initialisation
    Bonjour à toutes et à tous !

    Je me débats toujours avec mes objets, et déséspère parfois d'en voir le bout, mais quitte à être pris en flagrant délit d'optimisme forcené, je dirais que "si ça ne stagne ni ne régresse, ça progresse forcément"...

    J'avais implémenté une classe généraliste pour un arbre n-aire. Il se trouve que deux classes sont vouées à en dériver, la classe BayesianModel et la classe Lineage. Pour avoir de la flexibilité sur le type de données que contient l'arbre et n'implémenter les algorithmes de parcours qu'une seule fois, j'ai encapsulé les données dans chaque noeud dans un champs _data de classe "DataTypeForTree*", de laquelle dérive notamment la classe "BayesianModelData" (pour les Lineages on verra plus tard).

    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
    class KaryTree
    {
        public:
            // Constructors
            KaryTree* _parent;
            KaryTree(const DataTypeForTree &data);
            KaryTree(DataTypeForTree &data, std::vector<KaryTree* > children);
            ~KaryTree() ;
     
            // Setter/Getter
            DataTypeForTree* GetData(void);
            void SetChildren (std::vector<KaryTree* > children);
            void SetParent (KaryTree* parent);
     
            // Traversal algorithms
            void SearchDeepFirst (const VisitorInterface & visitor);
            void Accept(const VisitorInterface & visitor);
     
        private :
            std::vector<KaryTree* > _children; //private because it is the core of this class
     
        protected :
            DataTypeForTree* _data; // protected because it can change in the derived classes
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class BayesianModel : public KaryTree
    {
        public:
            BayesianModel(const BayesianModelDataType &data);
            virtual ~BayesianModel();
            //[...]
     
        protected:
        private:
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class BayesianModelDataType : public DataTypeForTree
    {
        public:
            BayesianModelDataType(const IMathematicalParametrizedFunction &fun, const std::string &param);
            BayesianModelDataType(const IMathematicalParametrizedFunction &fun);
            virtual ~BayesianModelDataType();
     
        protected:
        private:
        IMathematicalParametrizedFunction _fun;
        std::string _informedParameterOfParentFunction;
    };
    Dans la liste d'initialisation du constructeur de BayesianModel, j'appelle le constructeur de KaryTree. Seul souci, la classe de données nécessaire n'est pas la même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    BayesianModel::BayesianModel(const BayesianModelDataType &data) : KaryTree(data) // lui il a besoin d'un argument const DataTypeForTree
    {
        //ctor
    }
    Je crois qu'il y a un DataTypeForTree &rBase = cDerived à caser dans la liste d'initialisation mais
    1) J'en suis pas sûr
    2) Si c'est le cas, je ne sais pas comment l'écrire
    3) Pourriez-vous me guider ?

    Merci d'avance de votre aide !

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 774
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 774
    Par défaut
    Et comme cela

    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 KaryTree {
    public:
    //  Constructors
    /* ... */
        KaryTree(DataTypeForTree* data, std::vector<KaryTree* > children);
     
     
    /* ... */
    };
     
     
    class BayesianModel : public KaryTree {
    public:
        BayesianModel(BayesianModelDataType* data);
     
     
    /* ... */
    };

  3. #3
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Super j'essaie ça !!!

    Question de noob : j'arrête pas de lire qu'il faut éviter les pointeurs dans les interfaces, c'est pour ça que j'essayais de passer par des références. Y'a des cas où c'est vraiment nécessaire ?

    Merci de ta réponse !

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    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 153
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Seabirds Voir le message
    Y'a des cas où c'est vraiment nécessaire ?
    Oui, si le paramètre peut être null (NULL, nullptr).
    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.

  5. #5
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Oui, si le paramètre peut être null (NULL, nullptr).
    Bon, alors au moins pour les noeuds parents, c'est le cas. Merci bien !

    Génial, ça marche !!! Merci encore de votre aide et votre patience !

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il y a cependant quelque points que je voudrais mettre en avant, car j'ai l'impression que tu es parti pour avoir quelque problèmes...:
    1. Ton approche est beaucoup trop orientée donnée et pas assez orientée services
    2. Si le destructeur d'un de tes types dérivés est public et virtuel, c'est le destructeur du type de base'KaryTree) qui devrait l'être. L'autre solution consiste à déclarer le destructeur de ta classe de base (KaryTree ) comme étant protégé et non virtuel, mais pose certaines limitations dont il faudra que tu pèse le pour et le contre
    3. Typiquement, tout ce qui est collection n'a pas sémantique d'entité. Tu peux donc envisager d'utiliser le paradigme générique, mais, a priori, l'héritage (qui reste la relation la plus forte qui puisse exister entre deux classe) n'est pas la solution si plusieurs type doivent agir "comme une collection du type" que tu as créé (en deux mots : il faut se méfier de ceux qui disent que l'héritage est une relation X EST-UN Y : ce n'est pas ** forcément ** faux mais ce n'est pas toujours juste)

    Et de manière plus spécifique :
    1. le noeud parent devrait -- ad minima -- être transmis directement dans le constructeur, quitte à ce qu'il soit représenté sous la forme de nullptr dans le cas du noeud racine
    2. les enfants devraient pouvoir être manipulés (ajoutés, accédés, supprimés) "à l'unité" (un à un) et non uniquement "à l'ensemble"
    3. Quand ils existent (et encore faut il qu'il y ait une raison pour que ce soit le cas), les accesseurs (getXXX) devraient être des fonctions constante et renvoyer des valeurs ou des références constantes
    4. Si tu n'as pas de raison pour fournir un accesseur, tu n'as aucune raison pour fournir un mutateur (setXXX) et, meme si la présence d'un accesseur est cohérente, il y a de très fortes chances pour que celle du mutateur correspondant ne le soit pas

    Toutes ces remarques mériteraient chacune un "long discours dont j'ai le secret", ce qui aurait (cela ne m'arrive pas souvent) sans doute pour résultat de faire que le serveur refuse ma réponse "parce qu'excédant 65 536 caractères". Mais je suis certain que tous les aspects évoqués ici ont déjà été débattus en long, en large et en travers sur le forum (et que j'ai régulièrement pris part à la discussion).

    Je vais donc -- pour une fois -- te laisser cogiter quelque peu ces réponses "laminaires", mais n'hésite pas à me demander d'avantage de précision sur l'un ou l'autre point précis
    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

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

Discussions similaires

  1. héritage et polymorphisme
    Par julien.metais dans le forum Hibernate
    Réponses: 3
    Dernier message: 17/05/2009, 09h58
  2. Réponses: 10
    Dernier message: 17/07/2008, 20h01
  3. héritage et polymorphisme
    Par davdou dans le forum JSF
    Réponses: 2
    Dernier message: 23/11/2007, 09h51
  4. [C#] Information sur héritage et polymorphisme
    Par LE NEINDRE dans le forum C#
    Réponses: 21
    Dernier message: 14/06/2007, 11h00
  5. Réponses: 19
    Dernier message: 05/06/2007, 08h13

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