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 multiple en C++ : pourquoi l'héritage d'interfaces est insuffisant [Tutoriel]


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 : 50
    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
    Par défaut Héritage multiple en C++ : pourquoi l'héritage d'interfaces est insuffisant
    Bonjour à tous !

    Je viens de mettre en ligne un article, intitulé : Héritage multiple en C++ : Pourquoi l'héritage d'interfaces est insuffisant

    N'hésitez pas à faire donner votre avis, faire des remarques. L'article compare aussi des fonctionnalités de différents langages orientés objet, principalement C++, C# et Java. En tant que tel, j'espère qu'il pourra susciter des discussions intéressantes, sans sombrer dans le troll inter-langages.

    Bonne lecture !
    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.

  2. #2
    jmv
    jmv est déconnecté
    Membre chevronné Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Par défaut
    Super plaidoyer pour l'héritage multiple

    Enfin quelqu'un qui défend cette notion qu'il est "politiquement correct" de décrier.

    Merci

    juste 2 remarques :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    assert(montant > solde());
    J'espère que tu ne développe pas pour une banque !

    Et au chapitre 3-B, je me demande si le 1er diagramme de classe est correct (classe A définie 2 fois), et s'il l'est, il me semble identique au 2eme (même si on comprend bien grace à ces 2 diagrammes ce que tu veux montrer).

    Du bon boulot en tous cas.

    jmv

  3. #3
    screetch
    Invité(e)
    Par défaut
    Salut,
    c'est un très bon papier


    mais pour la partie 2B, je ne suis pas sur que l'héritage (multiple ou pas) soit la bonne solution, on dirait plutôt que quelqu'un a abusé de l'héritage. Dans ce cas, il faudrait plutot faire de la composition que de l'héritage (c'est un problème que je retrouve dans toutes les bibliothèques IHM que je connais; faire un widget c'est environ 8 niveaux d'héritage)

  4. #4
    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 : 50
    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
    Par défaut
    Citation Envoyé par screetch Voir le message
    mais pour la partie 2B, je ne suis pas sur que l'héritage (multiple ou pas) soit la bonne solution, on dirait plutôt que quelqu'un a abusé de l'héritage. Dans ce cas, il faudrait plutot faire de la composition que de l'héritage (c'est un problème que je retrouve dans toutes les bibliothèques IHM que je connais; faire un widget c'est environ 8 niveaux d'héritage)
    Je suis assez d'accord avec toi, le domaine de l'IHM abuse généralement des hiérarchies d'héritage profondes, et obligent souvent à dériver des classes fournies par la bibliothèque pour personnaliser le comportement (même si je trouve que la situation s'améliore, par exemple, en WPF, on peut faire moult personnalisations sans aucune dérivation, avec entre autre la notion de templates d'affichage qui permet d'indiquer comment un composant graphique logique va créer ses composants graphiques visuels).

    Le fait est qu'il faut tout de même faire avec. Et si le cas des IHM est emblématique des cas où l'on doit dériver de classes d'une hiérarchie existante et non modifiable, il n'est pas le seul.
    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.

  5. #5
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Article super intéressant , à faire lire à tous les javateux et autres csharpeux qui ne comprennent pas pourquoi on se sent frustré quand on code dans leur langage chéri.

    Seule petite remarque, je trouve dommage de présenter le NVI pour vérifier les contrats comme un avantage à l’héritage multiple de code. C’est plus un palliatif moins mauvais que ce qu’on a dans les autres langages. Théoriquement, les contrats font partie de l’interface de la fonction, pas de son code. Je ne l’aurais en tout cas pas mis en premier, je trouve les deux autres exemples beaucoup plus convaincants .

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 36
    Par défaut
    Très intéressant bravo !
    Surtout que je me suis dev C# et qu'en se moment je me met au c++, ça tombe à pic .

    J'ai survolé pour l'instant, mais je peut dire que sans héritage multiple, on peut aussi ne pas dupliquer de code, en général grâce à la composition.
    ça évite aussi d'avoir des classes "qui font tout", 1ère chose à laquelle je pense quand je vois écrit héritage multiple.

    En tout cas merci, j'ai hâte de m'y plonger ce soir

  7. #7
    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 : 50
    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
    Par défaut
    Citation Envoyé par jmv Voir le message
    juste 2 remarques :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    assert(montant > solde());
    J'espère que tu ne développe pas pour une banque !
    Rassure toi, tu peux dormir sur tes deux oreilles
    Citation Envoyé par jmv Voir le message
    Et au chapitre 3-B, je me demande si le 1er diagramme de classe est correct (classe A définie 2 fois), et s'il l'est, il me semble identique au 2eme (même si on comprend bien grace à ces 2 diagrammes ce que tu veux montrer).
    En effet, je ne pense pas qu'UML permette d'exprimer cette notion, et mes diagrammes ne sont donc probablement pas des diagrammes UML standards. Encore un exemple qui démontre que malgré ses désirs d'universalité, UML a été pensé avec certains types de langages en tête, et ne permet pas vraiment de représenter toutes les notions de tous les langages.
    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.

  8. #8
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    En effet, je ne pense pas qu'UML permette d'exprimer cette notion, et mes diagrammes ne sont donc probablement pas des diagrammes UML standards. Encore un exemple qui démontre que malgré ses désirs d'universalité, UML a été pensé avec certains types de langages en tête, et ne permet pas vraiment de représenter toutes les notions de tous les langages.
    Rien ne t'empêche de stéréotyper les héritages de <virtual>.

    A partir du moment où il s'agit d'un diagramme de conception/implémentation, et que donc le langage de programmation à ce stade est connu, il n'y a aucune ambiguïté à mon sens de le faire et exprime clairement la notion de non duplication (si j'ai bien compris) que tu souhaites mettre en avant.


    L'article est très intéressant sur plusieurs aspects bien que n'étant pas un pratiquant de ce langage et un adepte de l'héritage multiple en programmation à contrario de l'héritage multiple en conceptualisation. Ce que je veux dire c'est qu'en conceptualisation, j'aurais tendance à trouver suffisant ton premier diagramme en 2B (beaucoup plus clair)et je ne ferais pas le second diagramme du 2B par contre il correspondrait à une implémentation. Dans cet exemple, je reste aussi assez septique et sur ma faim sur ta conclusion sur la souplesse bien que je reconnais que le design est plus complexe.

    Il me semble aussi que dans ton second diagramme en 2B, il manque un lien pour montrer que DashBoardElementImplementation <implémente> IDashBoardElement.
    Images attachées Images attachées  

  9. #9
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Up.

    Merci pour ce bon article.

    J'approuve l'argument du NVI pour pouvoir tester des préconditions, des postconditions et écrire dans un fichier de log.
    J'approuve aussi l'exemple avec l'IHM.

    Par contre, je ne suis pas d'accord sur la pertinence de l'héritage multiple dans l'exemple avec les classes de politiques, où Tree dérive publiquement de ses classes de politique (Comparator, AllocationPolicy et BalancingPolicy).
    Le problème, c'est que tout ce qui se trouve en visibilité publique dans les classes de politique vient polluer la partie publique de l'interface de Tree.
    Pour offrir à l'utilisateur de la flexibilité à l'exécution, la solution qui me semble la plus propre serait que la classe Tree ait un constructeur qui prenne en paramètre ses classes de politique par référence constante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    explicit Tree(const Comparator& comp = Comparator(),
                  const AllocationPolicy& alloc = AllocationPolicy(),
                  const BalancingPolicy& balan = BalancingPolicy());
    D'ailleurs, c'est ce que fait std::set :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    explicit set(const key_compare& comp = key_compare(),
                 const allocator_type& alloc = allocator_type());
    Par exemple, admettons que je veuille avoir un ensemble ordonné d'entiers dont l'ordre, croissant ou décroissant, sera déterminé non pas à la compilation mais à l'exécution.
    Avec std::set, je peux faire ceci :
    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
    template<class T>
    class OrdreCroissantOuDecroissant {
    private:
        bool m_croissant;
    public:
        explicit OrdreCroissantOuDecroissant(bool croissant) : m_croissant(croissant) {}
        bool operator() (const T& x, const T& y) const {
            return m_croissant && x < y || !m_croissant && y < x;
        }
    };
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        const bool croissant = rand() % 2 == 0;
        const OrdreCroissantOuDecroissant<int> comp(croissant);
        std::set<int, OrdreCroissantOuDecroissant<int>> entiers(comp);
        entiers.insert(1);
        entiers.insert(2);
        entiers.insert(3);
        for(auto it = entiers.begin(); it != entiers.end(); ++it)
            std::cout << *it;
        return 0;
    }
    Pour revenir à Tree, si on veut vraiment autoriser l'utilisateur à modifier l'allocateur alors que l'objet Tree est déjà construit, à ses risques et périls, on peut toujours lui fournir des fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AllocationPolicy getAllocationPolicy() const;
    void setAllocationPolicy(const AllocationPolicy& alloc);

Discussions similaires

  1. Réponses: 4
    Dernier message: 05/06/2008, 23h20
  2. [heritage][conception]héritage multiple en java!
    Par soulhouf dans le forum Langage
    Réponses: 9
    Dernier message: 25/08/2005, 20h03
  3. L'héritage multiple est-il possible en Delphi ?
    Par SchpatziBreizh dans le forum Langage
    Réponses: 8
    Dernier message: 30/06/2005, 11h30
  4. utilisez vous l'héritage multiple ?
    Par vodosiossbaas dans le forum C++
    Réponses: 8
    Dernier message: 13/06/2005, 20h25
  5. [XML Schemas]héritage multiple
    Par nicolas_jf dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 10/06/2003, 12h55

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