class Foo : private Bar {
public:
// ...
};
[ Haut | Bas | Rechercher ]
Par example, la relation "Car has-a Engine" (une voiture a un moteur) peut être exprimé sous forme de composition:
class Engine {
public:
Engine(int numCylinders);
void start();
// Démarre ce moteur (Engine)
};
class Car {
public:
Car() : e_(8) { }
// Initialise cette voiture (Car) avec 8 cylindres
void start() { e_.start(); } //
Démarre cette voiture (Car) en démarrant son moteur (Engine)
private:
Engine e_;
// Une voiture a un moteur (Car has-a Engine)
};
La même relation "has-a" peut être exprimée en utilisant l'héritage privé:
class Car : private Engine
{ // Une voiture a un moteur (Car has-a Engine)
public:
Car() : Engine(8) { } //
Initialise cette voiture (Car) avec 8 cylindres
Engine::start;
// Démarre cette voiture (Car) en démarrant son moteur
(Engine)
};
Il y a plusieurs similarités entre ces deux formes de composition:
[ Haut | Bas | Rechercher ]
Normalement il n'est pas souhaitable pour vous d'accéder aux éléments internes de trop d'autres classes, et l'héritage privé vous donne ce petit plus de possibilités (et de responsabilités). Mais l'héritage privé n'est pas à proscrire; il est juste plus lourd à maintenir car il accroit la probabilité que quelqu'un changera quelque chose qui cassera votre code.
Une utilisation légitime et à long terme de l'héritage privé est lorsque que vous souhaitez construire une class Fred qui utilises le code de class Wilma, et le code de class Wilma doit appeler des fonctions membres de votre nouvelle class Fred. Dans ce cas, Fred appelle des fonctions non-virtuelles dans Wilma, et Wilma appelle les fonctions (normalement virtuelles pures) en son sein, qui sont surchargés par Fred. Cela est bien plus difficile a obtenir à l'aide de la composition.
class Wilma {
protected:
void fredCallsWilma()
{
cout <<
"Wilma::fredCallsWilma()\n";
wilmaCallsFred();
}
virtual void
wilmaCallsFred() = 0; // Fonction virtuelle pure
};
class Fred : private Wilma {
public:
void barney()
{
cout << "Fred::barney()\n";
Wilma::fredCallsWilma();
}
protected:
virtual void wilmaCallsFred()
{
cout << "Fred::wilmaCallsFred()\n";
}
};
[ Haut | Bas | Rechercher ]
Généralement, Non.
Vu de la fonction membre ou d'un ami d'une classe dérivée de manière privée; la relation avec la classe de base est connue et la conversion ascendante de PrivatelyDer* en Base* (ou de PrivatelyDer& en Base&) est sûre; aucun cast n'est nécessaire ou recommandé.
Cependant, les utilisateurs de PrivatelyDer doivent éviter une conversion non-sûre car cela est basé sur une décision privée de PrivatelyDer, et est susceptible de changer sans avertissement.
[ Haut | Bas | Rechercher ]
Différences: L'héritage protégé permet aux classes dérivées des classes dérivées de connaître la relation d'héritage. Donc, vos petits enfants sont exposés aux détails de votre implémentation. Cela est à la fois un bénéfice (les sous-classes de la classe dérivée protégée peuvent exploiter la relation avec la classe de base protégée) et un coût (la classe dérivée protégée ne peut changer la relation sans potentiellement casser ses classes dérivées).
L'héritage protégée utilise la syntaxe : protected
class Car : protected Engine {
public:
// ...
};
[ Haut | Bas | Rechercher ]
Prenez l'exemple des classes suivantes::
class B
{ /*...*/ };
class D_priv : private B { /*...*/};
class D_prot : protected B {
/*...*/};
class
D_publ : public B { /*...*/};
class UserClass
{ B b; /*...*/ };
Aucune des classes dérivées ne peut accéder aux parties privées de B. Dans D_priv, les parties publiques et protégées de B sont privées. Dans D_prot, les parties publiques et protégées de B sont protégées. Dans D_publ, les parties publiques de B sont publiques et les parties protégées de B sont protégées (D_publ est kind-of B). La class UserClass peut accéder uniquement aux parties publiques de B, ce qui isole UserClass de B.
Pour avoir un membre public de B qui soit également public dans D_priv ou dans D_prot, préfixez le nom du membre par B::. Par exemple, pour que le membre B::f(int,float) soit public dans D_prot, cela donnerai:
class D_prot
: protected B {
public:
using B::f;
// Note: Et non pas using B::f(int,float)
};
[ Haut | Bas | Rechercher ]
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:54:32 PDT 2003