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 :

[conception]polymorphisme statique ou dynamique ?


Sujet :

C++

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut [conception]polymorphisme statique ou dynamique ?
    Le problème est simple mais je ne sais quelle conception choisir.
    J'ai 2 structures de données : Cube et Slice. Ces 2 structures implémentent une méthode read().
    J'ai créé une classe ReadDataFile qui est chargée de lire un fichier et de remplir les structures de type Cube ou Slice.
    J'ai 2 possibilités pour ReadDataFile :
    1/ Soit 1 template du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template<typename T>
    class ReadDataFile
    {
    public:
    ReadDataFile(T data, const string& filename) : data_(data) { data_.read(filename); }
     
    private:
    T& data_;
    };
    Ce qui donne à l'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Cube data;
    ReadData<Cube> readData(data, "fichier.txt");
    etc ...

    Mais je peux aussi choisir d'utiliser l'héritage comme par exemple :
    Cube et Slice qui héritent d'une classe de base Data possédant une fonction virtuelle pure read() qui est implémentée dans Cube et Slice.
    A ce moment là, ReadDataFile n'aurait plus besoin d'être template, et pourrait être écrite comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class ReadDataFile
    {
    public:
    ReadDataFile(Data& data, const string& filename) : data_(data) { data_.read(filename); }
     
    private:
    Data& data_;
    };
    Je pense que la 2eme conception est meilleure, mais bon, je ne saurais pas trop le justifier. Qui peux me dire quelle est la meilleure des 2 conceptions dans ce cas précis ?

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Je ne vois pas ce que t'apportes la seconde solution.
    Boost ftw

  3. #3
    Membre éclairé Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Points : 693
    Points
    693
    Par défaut
    Par rapport à ton exemple, j'ai l'impression que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Cube data; //ou un Slice
    data.read("fichier.txt");
    serait le plus simple.

    Mais sans doute as tu simplifié ton code au maximum, et dans ce cas, il pourrait être intéressant de savoir comment tu utilises ta classe ReadDataFile, pour répondre à ta question.

  4. #4
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    Citation Envoyé par MatRem
    Par rapport à ton exemple, j'ai l'impression que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Cube data; //ou un Slice
    data.read("fichier.txt");
    serait le plus simple.

    Mais sans doute as tu simplifié ton code au maximum, et dans ce cas, il pourrait être intéressant de savoir comment tu utilises ta classe ReadDataFile, pour répondre à ta question.
    Oui, j'ai pas mal simplifié car en fait ReadDataFile gère d'autres choses comme la gestion des exceptions et je voulais donc encapsuler les fonctions propres à la lecture d'un Cube de données dans la classe Cube.

    Mais en fait, c'était juste pour savoir s'il valait mieux (même dans le cas simplifié) utiliser les templates ou l'héritage.
    Parfois, je ne sais pas trancher quand les 2 conviennent.

  5. #5
    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,

    A mon sens, il est intéressant de se poser la question de savoir si, dans le cas présent, cube et slice sont susceptibles de devoir cohabiter, dans un vecteur par exemple, ou dans tout autre conteneur...

    Si tu est *certain* que, au pire, tu n'aura jamais qu'un vecteur de cube OU un vecteur de slice, mais que tu n'aura jamais un vecteur qui contiendra l'un et l'autre, l'utilisation des templates peut s'avérer intéressante... Il faudra cependant envisager la création de traits pour provoquer la vérification à la compilation

    Si, par contre, tu envisage comme plausible d'avoir un vecteur qui contienne en meme temps des cubes et des slices, la solution interface/ implémentation classique me semble etre la seule solution à court terme
    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

  6. #6
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    Non, un même conteneur ne contiendra jamais à la fois des objets Cube et des objets Slice.
    Adjugé pour les templates alors.

  7. #7
    Membre éclairé Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Points : 693
    Points
    693
    Par défaut
    A priori la version "templatée" sera un tout petit peu plus efficace au niveau execution.
    Elle t'évite aussi d'être obligé d'utiliser l'héritage (mais là, il faut voir si le fait d'hériter ne rend pas ton code plus clair).

    Par contre, ça peut être lourd de devoir écrire l'argument template à chaque fois.

    Il faudra cependant envisager la création de traits pour provoquer la vérification à la compilation.
    Pour vérifier quoi à la compilation? juste que T est bien Cube ou Slice?

    (je commence juste à lire c++ template, et je n'ai pas l'impression que ce soit le but des traits... )

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Pour ton histoire d'exception, je te propose ceci.
    Dans Cube et Slice tu définis un type exception_type, comme ça dans ReadDataFile, tu peux balancer un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    throw typename T::exception_type(arguments);
    Pour les traits, un article va être publié sur developpez demain sur le sujet!

    Sinon, si les deux ne doivent être stockés ensemble, je penche pour les templates. Pour alléger la notation ReadDataFile<Cube> et <Slice>, tu n'as qu'à faire des typedefs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef ReadDataFile<Cube> rdfCube;
    typedef ReadDataFile<Slice> rdfSlice;
    Par exemple...
    De plus tes références permettent de manipuler des Cube et Slice à travers ta classe ReadDataFile, je trouve cette solution efficace, comparée à celle de l'héritage, utilise uniquement quand on veut faire un traitement global en série, généralement. Donc stocker tous les objets de tous les types ensemble à travers une base commune.

    PS :
    Une classe de trait (trait class), généralement template, définit des caractéristiques ou des fonctions associées à un type donné. Cela permet donc d'ajouter de l'information à des types que l'on ne peut pas modifier.
    Source : http://c.developpez.com/faq/cpp/?pag...S_classe_trait

Discussions similaires

  1. Polymorphisme statique et dynamique
    Par oodini dans le forum Langage
    Réponses: 6
    Dernier message: 14/07/2014, 22h40
  2. Polymorphisme Dynamique et Polymorphisme statique
    Par ABAM3194 dans le forum Visual C++
    Réponses: 9
    Dernier message: 15/11/2013, 19h02
  3. Réponses: 2
    Dernier message: 20/10/2008, 09h24
  4. [Architecture/strategie] conception de site web dynamique
    Par epoz dans le forum Général Conception Web
    Réponses: 3
    Dernier message: 28/11/2005, 12h11
  5. Réponses: 2
    Dernier message: 19/08/2005, 16h02

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