Date de première publication : 2012/10/12
Polymorphisme : virtual
- Construire une classe
Personneavec un attribut privé "nom" de typestring
La classe string appartient à l'espace de nommage std. Voici les trois manières d'utiliser
le type string :
std::stringusing std::string;- using namespace std;
- Ajouter une méthode publique
afficher()qui affiche le nom sur la sortie standard - Ajouter un constructeur public qui prend en paramètre une chaîne et qui initialise le nom
- Instancier et afficher une personne
p1 - Déclarer une classe
Etudiantqui dérive dePersonne - Instancier et afficher un étudiant
e - Corriger sans modifier la classe
Personne
Le compilateur râle d'abord parce qu'il n'y a pas de constructeur par défaut.
Si on fournit un constructeur avec paramètre, il faut bien utiliser la liste d'initialisation pour appeler
le seul constructeur défini dans la classe Personne.
- Ajouter une méthode publique
info()dans les deux classes. Dans la classePersonne, la méthode affiche sur la sortie standard "Personne" et pour la classeEtudiant, "Etudiant". - Appeler
p1.info()ete.info(). Que remarquez-vous ? - Créer un objet
Personne p2 = e;. Appelerinfo(), que se passe-t'il ? - Instancier une
Personne * pp1 = new Etudiant("dd");Appelerinfo(), que se passe-t'il ? - Ajouter le mot-clé
virtualsur chacune des méthodesinfo()? Que remarquez-vous ?
Si vous avez codé proprement, vous avez fait un delete sur pp1. Pour que le destructeur d'Etudiant soit bien appelé, malgré
le fait que pp1 est de type Personne *, il faut que les destructeurs soient virtual eux-aussi. C'est très facile à vérifier :
- Ajouter les destructeurs aux classes définies avec un simple affichage sur la console.
- Vérifier que
~Etudiant()n'est pas appelé lors dudelete pp1; - Ajouter virtual à
~Personne()et voir que cela marche bien maintenant
Troncature
- Ajouter le code ci-dessous et appelez ces fonctions en passant une instance d'
Etudiant. Que remarquez-vous ?
void afficher1(Personne p) { p.info(); }
void afficher2(Personne& p) { p.info(); }
void afficher3(Personne* p) { p->info(); }
La perte d'informations liée à l'usage d'afficher1() s'appelle une troncature de type. On ne l'observe pas
lorsque l'on utilise une référence ou un pointeur.
On aurait pu nommer afficher1() et afficher3() avec le même identifiant. Le compilateur aura fait la différence avec
le type du paramètre (surcharge). La différentiation n'est pas possible entre afficher1() et afficher2().


