[19] Héritage - Les bases,Héritage - Les bases

(Une partie de C++ FAQ Lite fr, Copyright © 1991-2002, Marshall Cline, cline@parashift.com)

Traduit de l'anglais par Stéphane Bailliez

Les FAQs de la section [19]


[19.1] L'héritage est il important en C++?
Oui.

L'héritage est la différence fondamentale entre la programmation avec des types de données abstraits (abstract data type - ADT) et la programmation OO.

[ Haut | Bas | Rechercher ]


[19.2] Quand dois-je utiliser l'héritage?
Pour exprimer la spécificité.

L'être humain effectue une abstraction de deux manières: l'association (part-of) et la généralisation (kind-of). Une Renault Espace est une sorte de (is-a-kind-of) Voiture et une Renault Espace a (has-a) un Moteur, des Pneus, etc... La notion d'association/appartenance fait partie du monde du développement depuis que la programmation ADT a été reconnue, l'héritage ajoute "l'autre" majeure dimension de la décomposition.

[ Haut | Bas | Rechercher ]


[19.3] Comment exprime t-on l'héritage en C++?
A l'aide de la syntaxe : public

class Car : public Vehicle {
public:
// ...
};

On mentionne cette relation de pluseiurs manières:

(Note: cette FAQ est relative à l'héritage public; l'héritage private et l'héritage protectedsont différents.)

[ Haut | Bas | Rechercher ]


[19.4] Est ce légal de convertir un pointeur sur une classe dérivée en sa classe de base ?
Oui.

Un objet d'une classe dérivée est une sorte de (is a kind of) la classe de base. La conversion d'un pointeur sur une classe dérivée en un pointeur sur sa classe de base est donc parfaitement légal est arrive constamment. Par example si je pointe sur une voiture, je pointe en fait sur un véhicule, donc convertir de Car* vers un Vehicle* est tout a fait légal et normal.

void f(Vehicle* v);
void g(Car* c) { f(c); } // autorisé, pas de cast nécessaire

(Note: this FAQ has to do with public inheritance; private and protected inheritance are different.)

[ Haut | Bas | Rechercher ]


[19.5] Quelle est la différence entre public:, private:, et protected:?
[Haut

[ Haut | Bas | Rechercher ]


[19.6] Pourquoi mes classes dérivées ne peuvent elles accéder aux élements en private: de ma classe de base?
Pour vous protéger de changements pouvent subvenir ultèrieurement dans la classe de base.

Les classes dérivées ne peuvent accéder aux membres privées de la classe de base. Cela permet d'éviter les classes dérivées de subir un changement réalisé dans la classe de base. Si vous avez 15 classes dérivées utilisant des membres de la classe de base. Un changement de la classe de base vous forcera à modifier vos 15 classes dérivées !

[ Haut | Bas | Rechercher ]


[19.7] Comment puis je protéger mes classes dérivées de l'impact concernant les changements des attributs de la classe de base?
Une classe a deux interfaces distinctes avec deux types de clients distincts: Il est donc préférable de garder les attributs de la classe de base en private:, et d'utiliser des accesseurs en protected:inline, de cette manière les classes dérivées accéderont aux attributs privatede la classe de base et cela minimisera voire supprimera l'impact d'un changement des données en private sur les classes dérivées.

[ Haut | Bas | Rechercher ]


[19.8] I've been told to never use protected data, and instead to always use private data with protected access functions. Is that a good rule?

Nope.

Whenever someone says to you, "You should always make data private," stop right there — it's an "always" or "never" rule, and those rules are what I call one-size-fits-all rules. The real world isn't that simple.

Here's the way I say it: if I expect derived classes, I should ask this question: who will create them? If the people who will create them will be outside your team, or if there are a huge number of derived classes, then and only then is it worth creating a protected interface and using private data. If I expect the derived classes to be created by my own team and to be reasonable in number, it's just not worth the trouble: use protected data. And hold your head up, don't be ashamed: it's the right thing to do!

The benefit of protected access functions is that you won't break your derived classes as often as you would if your data was protected. Put it this way: if you believe your users will be outside your team, you should do a lot more than just provide get/set methods for your private data. You should actually create another interface. You have a public interface for one set of users, and a protected interface for another set of users. But they both need an interface that is carefully designed — designed for stability, usability, performance, etc. And at the end of the day, the real benefit of privatizing your data is to avoid breaking your derived classes when you change that data structure.

But if your own team is creating the derived classes, and there are a reasonably small number of them, it's simply not worth the effort: use protected data. Some purists (translation: people who've never stepped foot in the real world, people who've spent their entire lives in an ivory tower, people who don't understand words like "customer" or "schedule" or "deadline" or "ROI") think that everything ought to be reusable and everything ought to have a clean, easy to use interface. Those kinds of people are dangerous: they often make your project late, since they make everything equally important. They're basically saying, "We have 100 tasks, and I have carefully prioritized them: they are all priority 1." They make the notion of priority meaningless.

You simply will not have enough time to make life easy for everyone, so the very best you can do is make life easy for a subset of the world. Prioritize. Select the people that matter most and spend time making stable interfaces for them. You may not like this, but everyone is not created equal; some people actually do matter more than others. We have a word for those important people. We call them "customers."

[ Haut | Bas | Rechercher ]


[19.9] Okay, so exactly how should I decide whether to build a "protected interface"?

Three keys: ROI, ROI and ROI.

Every interface you build has a cost and a benefit. Every reusable component you build has a cost and a benefit. Every test case, every cleanly structured thing-a-ma-bob, every investment of any sort. You should never invest any time or any money in any thing if there is not a positive return on that investment. If it costs your company more than it saves, don't do it!

Not everyone agrees with me on this; they have a right to be wrong. For example, people who live sufficiently far from the real world act like every investment is good. After all, they reason, if you wait long enough, it might someday save somebody some time. May be. We hope.

That whole line of reasoning is unprofessional and irresponsible. You don't have infinite time, so invest it wisely. Sure, if you live in an ivory tower, you don't have to worry about those pesky things called "schedules" or "customers." But in the real world, you work within a schedule, and you must therefore invest your time only where you'll get good pay-back.

Back to the original question: when should you invest time in building a protected interface? Answer: when you get a good return on that investment. If it's going to cost you an hour, make sure it saves somebody more than an hour, and make sure the savings isn't "someday over the rainbow." If you can save an hour within the current project, it's a no-brainer: go for it. If it's going to save some other project an hour someday may be we hope, then don't do it. And if it's in between, your answer will depend on exactly how your company trades off the future against the present.

The point is simple: do not do something that could damage your schedule. (Or if you do, make sure you never work with me; I'll have your head on a platter.) Investing is good if there's a pay-back for that investment. Don't be naive and childish; grow up and realize that some investments are bad because they, in balance, cost more than they return.

[ Haut | Bas | Rechercher ]


E-mail Marshall Cline Ecrire à l'auteur, au traducteur, ou en savoir plus sur la traduction.
C++ FAQ Lite fr | Table des matières | Index | A propos de l'auteur | © | Téléchargez votre propre copie ]
Dernière révision Sun Apr 13 23:53:59 PDT 2003