Absolument pas
Les règles à appliquer pour l'héritage public sont relativement simples en soi.
Mais le fait est que ce sont des règles de conception et qu'aucun langage, aucun programme, aussi perfectionné soit-il ne pourra jamais déterminer si une décision conceptuelle est logique et cohérente dans un contexte donné.
Il faut donc, comme je le dis, les appliquer avec la plus grande rigueur, si on veut éviter les problèmes par la suite
A ce jour, personne n'a encore pu trouver une situation dans laquelle l'héritage protégé se justifieraitTu omets de dire que l'héritage, c'est aussi l'héritage protégé
Parce que, sauf cas exceptionnel, je préfères de loin l'aggrégation à l'héritage privé qui est une relation EST-INMPLEMENTE-EN-TERMES-DEet l'héritage privé
C'est une technique propre à un autre paradigme, sans objet par rapport à l'héritage public (et qui, au passage, doit néanmoins respecter les règles de l'héritage public )le CRTP,
Ce n'est qu'un cas particulier de l'héritage public, qui justifie encore d'avantage que l'on applique scrupuleusement les règles de conceptions liées à l'héritage publicl'héritage multiple,
Ce n'est qu'un cas particulier du cas particulier ci-dessus. Je n'irai pas jusqu'à dire qu'il s'agit sans doute d'une erreur de conception si tu te retrouves dans une situation dans laquelle tu en as besoin, mais je suis néanmoins pas loin de le penser.virtuel...
J'admets volontiers que l'héritage virtuel est la base de bibliothèques de qualité qui ont fait fureur il y a quelques années (Je pense à la VCL entre autres), mais cela ne change en rien mon avis sur la question: conceptuellement parlant, c'est qu'une décision a imposé un god objet quelque part, et je suis contre les god objets de manière générale
L'héritage privé / agrégation est souvent utilisé pour ajouter une fonctionnalité à une classe, dès que la classe contenant la fonctionnalité à ajouter ne doit pas être construite seule l'héritage privé est meilleur (ce qui arrive quand même la plupart du temps).VS
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 class SomeFunctionality { protected: SomeFunctionality(int i): m_i(i) { }; void functionality() { std::cout << m_i; } private: int m_i; }; class Foo : private SomeFunctionality { public: Foo(): SomeFunctionality(42) { } using SomeFunctionality::functionality; };Dans le cas de l'agrégation, soit on utilise une amitié (et tous les champs privés sont visible) soit la fonctionnalité peut être construite seule. (A moins que quelque chose m'échappe ).
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 template <class F> class SomeOtherFunctionality { SomeOtherFunctionality(int i): m_i(i) { }; void functionality() { std::cout << m_i; } int m_i; friend F; }; class Bar { public: Bar(): m_functionality(42) { } void functionality() { m_functionality.functionality(); } private: SomeOtherFunctionality<Bar> m_functionality; };
Attention, je n'ai jamais dit que je refusais systématiquement l'héritage privé
J'aurais sans doute du dire "sauf cas particulier" au lieu de "sauf cas exceptionnel", tant il est vrai que l'on ne peut pas considérer les cas dans lesquels l'héritage privé est nécessaire comme "exceptionnels" .
Mais, de prime abord, j'envisagerai "par défaut" de préférence une relation "plus souple" d’agrégation qu'un héritage privé, que je réserve pour les cas où "l'agrégation ne représente définitivement pas une alternative viable (ou efficace)".
L'héritage privé est une technique merveilleuse, mais comme bon nombre de techniques de cet acabit, il faut veiller à ne l'utiliser que quand c'est réellement nécessaire. Trop souvent, les gens ont sans doute tendance à l'utiliser à tord et à travers, ce qui nuit à la qualité de leur développement en général
Je te parle du type de relation qui existe entre une classe qui hérite (que ce soit de manière publique ou privée) d'une autre par rapport à celle qui existe entre une classe qui agrège une autre.
Ou, si tu préfères, des implications qu'il faudrait prendre en compte pour arriver à "faire autrement" si la fantaisie (ou le besoin) s'en faisait sentir.
Avec une agrégation, tu peux envisager de changer le type de l'objet agrégé sans rien avoir à modifié si le nouveau type de l'objet présente la même interface que le type d'origine. Dans le pire des cas, ce ne seront que quelques fonctions qui devront être corrigées pour s'accorder avec le nouveau type.
Alors qu'avec un héritage -- quel qu'il soit -- ce n'est pas seulement ce qui utilise l'interface publique de la classe de base que tu devras modifier mais aussi l'ensemble de ce qui utilise l'interface protégée de la classe de base, au stricte minimum (sans même compter une éventuelle amitié).
Pour faire une analogie simple : il existe très vraisemblablement une relation beaucoup plus forte entre toi et tes parents ou entre toi et tes enfants que la relation qui pourrait exister entre toi et tes voisins. Et ne vient pas me poser la question de savoir ce qui se passe si tes voisins sont justement tes parents ou tes enfants, ce serait faire preuve de mauvaise foi !
En outre, s'il est vrai que l'héritage -- quel qu'il soit -- permet énormément de choses, il ne faut pas oublier qu'il est soumis à des restrictions importantes. A tel point qu'il est beaucoup plus facile de se passer de l'héritage -- moyennant certaines adaptations du code ou du schéma de pensée -- que de l'agrégation, qui est une relation qui, rappelons le, existe dans tout langage permettant la programmation structurée
Effectivement, ma phrase n'est pas forcément claire et manque de ponctuation, dsl.
"dès que la classe contenant la fonctionnalité à ajouter ne doit pas être construite seule, alors l'héritage privé est meilleur"
-> Dans mon exemple, si on souhaite interdire la création de SomeFunctionality ou de SomeOtherFunctionality quand elle sont utilisées seules (sans agrégation/héritage privée), l'héritage privé est meilleur.
ex:En espérant que se soit plus clair.
Code : Sélectionner tout - Visualiser dans une fenêtre à part SomeFunctionality f; // non autorisé car n'a pas de sens, la fonctionnalité n'a un sens que lorsqu'elle complète une autre classe
OK, il s'agit donc d'un mixin.
L'argument est également valable pour l'héritage protégé Il est souvent utilisé avec les classes de politique.
ok ça je comprends.Les préconditions ne peuvent pas être renforcées dans le type dérivé
les postconditions ne peuvent pas être assouplies dans le type dérivé
Les invariants doivent être respectés
Il faut considérer tout membre et toute fonction membre (quelle que soit la visibilité) comme étant un invariant.
Par contre, ce qui suit dans votre discussion...
Quelqu'un peut me traduire?
Non. Le C++, c'est comme le sexe : il ne faut pas brûler les étapes.
Tu découvriras tout ça par toi-même.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager