Vous êtes sur la page 1sur 78

04 POO : HÉRITAGE ET COMPOSITION

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL


HÉRITAGE

¤ L’héritage permet de former une nouvelle classe à partir de classes existantes.

¤ La nouvelle classe (classe fille, sous-classe) hérite des attributs et des méthodes des
classes à partir desquelles elle a été formée (classes mères, super-classes).

¤ De nouveaux attributs et de nouvelles méthodes peuvent être définis dans la classe


fille.

¤ Des méthodes des classes mères peuvent être redéfinies dans la classe fille.

¤ La redéfinition de méthode consiste à (re)définir dans la classe fille le comportement


(code de la méthode) qui existait déjà dans une classe mère. Si une méthode d’une
classe mère n’est pas redéfinie dans la classe fille, alors le code défini dans la classe
mère sera utilisé « tel quel » sur les instances de la classe fille.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 2
HÉRITAGE: PRINCIPE

¤ Il représente la relation: EST-UN


> Un chat est un animal
> Une moto est un véhicule
> Un cercle est une forme

¤ Alors que l'objet membre représente la relation: A-UN


> Une voiture a un moteur

¤ L'héritage est mis en œuvre par la construction de classes dérivées.

¤ Intérêt :
> Réutilisation Utiliser une classe existante…
+ En lui rajoutant des membres
+ et/ou en modifiant certains de ses comportements

> sans modifier le code de la classe existante.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 3
HÉRITAGE: EXEMPLES

¤ Le graphe de l'héritage est comme suit:

¤ La classe animal est la classe de base (classe supérieure),

¤ Les classes chat, chien et oiseau sont des classes dérivées (sous-classes).

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 4
HÉRITAGE: UNE CLASSE DÉRIVÉE

¤ Une classe dérivée modélise un cas particulier de la classe de base et, est donc
enrichie d'informations supplémentaires.

¤ La classe dérivée possède les propriétés suivantes:


> contient les données membres de la classe de base (selon le degré de visibilité),
> peut en posséder de nouvelles,
> possède (à priori) les méthodes de sa classe de base (selon le degré de visibilité),
> peut redéfinir (masquer) certaines méthodes,
> peut posséder de nouvelles méthodes.

¤ La classe dérivée hérite des membres de la classe de base.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 5
HÉRITAGE : SYNTAXE

¤ C++ permet aussi d’utiliser l’héritage protected et private, rarement utilisés.

¤ Si aucun mode de protection n’est déclaré, le mode private sera appliqué

¤ Souvent, on utilise l’héritage simple : une classe fille a une classe mère.

¤ On parle d’héritage multiple quand une classe fille a plusieurs classes mères.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 6
HÉRITAGE : INTÉRÊTS

¤ Intérêts de l’héritage :
> Favoriser la réutilisation.
> Factoriser le code.
> Catégoriser les concepts dans une relation de généralisation Chaque concept est
caractérisé par ses différences par rapport à son (ses) parent(s).

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 7
HÉRITAGE: EXEMPLES DE DÉCLARATIONS

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 8
HÉRITAGE: ACCÈS AUX MEMBRES HÉRITÉS

¤ Si la classe dérivée hérite publiquement de la classe de base,


> les membres de la classe dérivée auront accès aux membres publics (champs et
méthodes) de la classe de base,
> par contre, ils n'auront pas accès aux membres privés de la classe de base.
¤ Héritage privé

public private
protected inacessibles
private
dans la classe de base dans la classe dérivée
¤ Héritage protégé

public protected
protected inacessibles
private
COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA
ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 9
HÉRITAGE : REDÉFINITION DES FONCTIONS MEMBRES
¤ La fonction affiche de l’exemple précèdent est membre de la classe de base véhicule.
¤ Elle n'affiche que les membres privés de cette classe.
¤ On ne peut pas donc afficher le nombre de moteurs dans la sous-classe avion par exemple.
¤ Pour faire cela, nous allons définir dans la classe dérivée une fonction portant le même nom
et, qui aura pour rôle d'afficher les données privées de la classe dérivée.
¤ On parle alors de redéfinition d'une fonction de la classe de base.

¤ Quand une méthode est redéfinie dans la classe fille, elle doit être déclarée avec la même
signature que dans la classe mère.
¤ Le code d’une méthode redéfinie fait souvent appel à la méthode de la classe mère (super
méthode) NomDeLaClasseMere::NomDeLaMethode(arguments)

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 10
HÉRITAGE: CONSTRUCTEURS

¤ Les constructeurs des classes mères ne peuvent être utilisés pour construire des
instances de la classe fille
> Il faut définir de nouveaux constructeurs.

¤ Les constructeurs de la classe fille font appel aux constructeurs des classes mères au
début de la liste d’initialisations.
> Pour créer un avion il faut d’abord créer un vehicule

¤ Le constructeur de la classe de base (véhicule) est donc appelé avant le constructeur


de la classe dérivée (avion).

¤ Si dans l'appel du constructeur de la classe dérivée, le nom du constructeur de la


classe de base n'est pas mentionné explicitement, le constructeur par défaut de la
classe de base sera pris en compte.

¤ Si la classe de base a un constructeur autre que celui par défaut, la classe dérivée doit
avoir un constructeur.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 11
HÉRITAGE: DESTRUCTEURS

¤ Le destructeur des classes mères est toujours appelé implicitement après l’exécution
du destructeur de la classe fille.

¤ On n’appelle jamais explicitement le destructeur des classes mères dans le destructeur


de la classe fille.

¤ De façon symétrique, le destructeur de la classe de base est appelé après le


destructeur de la classe dérivée.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 12
CONTRÔLE DES ACCÈS

¤ Les droits d'accès protègent les données et les méthodes et réalisent aussi
l'encapsulation.
¤ Les droits d'accès sont accordés aux fonctions membres ou aux fonctions globales.
¤ L'unité de protection est la classe: tous les objets de la classe bénéficient de la même
protection.
¤ Il y a 3 catégories de protection:
> un membre public est accessible à toute fonction,
> un membre private n'est accessible qu'aux fonctions membres de la classe ou aux
fonctions amies,
> un membre protected n'est accessible qu'aux fonctions membres de la classe de
base ou des classes dérivées ou aux fonctions amies.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 13
AFFECTATION: CONVERSION AUTOMATIQUE

¤ Un objet d'une classe dérivée peut toujours être utilisé au lieu d'un objet de sa classe
de base. (N’est applicable que dans le cas de la dérivation public).`

¤ Par exemple, un avion est un véhicule. Mais l'inverse n'est pas vrai, un véhicule n'est
pas nécessairement un avion.

¤ Conversion implicite de tout avion EST-UN véhicule. Le compilateur fait une copie en
ignorant les membres excédentaires (nbre_moteurs).

¤ Un véhicule n'est pas forcément un avion. On ne peut pas deviner quelles seront les
valeurs manquantes (dans cet exemple: nbre_moteurs). Un véhicule n'a pas toutes les
données d'un avion.

¤ Traiter un type dérivé comme s’il était son type de base est appelé transtypage
ascendant ou surtypage (upcasting).

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 14
CONVERSION AUTOMATIQUE

p Si B hérite de A, alors toutes les instances


de B sont aussi des instances de A, et il
est donc possible de faire :

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 15
TRANSTYPAGE

p Traiter un type dérivé comme s’il était son


type de base est appelé transtypage
ascendant ou surtypage (upcasting).

p A a; B b; C c;
p a=b; // Ok
p a=c; // Ok
p b=c; // Ok
p b=a; // NOK
p c=a;//NOK 84

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 16
PRINCIPES

p L’héritage permet:
n Concevoir une architecture solide
n Développement en mode bloc
n La réutilisation du code déjà écrit
n L’ajout de nouvelles fonctionnalités
n La modification d’un comportement existant
(redéfinition)

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 17
REDÉFINITION VS SUR-DEFINITION

p Il ne faut pas mélanger la redéfinition et la sur-


définition :
n Une sur-définition ou surcharge (overloading) Permet
d’utiliser plusieurs méthodes qui portent le même nom
au sein d’une même classe avec une signature
différente.
n Une redéfinition (overriding) permet de fournir une
nouvelle définition d’une méthode d’une classe
ascendante pour la remplacer. Elle doit avoir une
signature rigoureusement identique À la méthode
parente.
q Un objet garde toujours la capacité de pouvoir
redéfinir une méthode afin de la réécrire ou de la
compléter.
COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA
ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 18
HÉRITAGE MULTIPLE

p ]

p En C++, une classe peut être dérivée à partir de


plusieurs classes de bases (héritage multiple)

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 19
SYNTAXE

class A { class B {
public: public:
A () { B (int a, int b, int c){
cout<<« Je suis A()»endl; cout<<« Je suis B()»endl;
} }
A (int i) { B (int a){
cout<<« Je suis A(int)»endl; cout<<« Je suis B(int)»endl;
} }
A (int i, int j) { B (int a, int b){
cout<<« Je suis A(int,int)»endl; cout<<« Je suis B(int,int)»endl;
} }
}; };

Class C: public A, public B {


public:
C () {
}
92
};
COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA
ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 20
APPEL DES CONSTRUCTEURS

p Les constructeurs sont appelées dans l’ordre de


l’héritage.
p Il y a la possibilité de spécifier lequel des
constructeurs de la classe mère sera appelé.
p Soit A, B et C trois classes. C hérite de B et C.
p Un constructeur de C peut prendre les formes
suivantes:
n C(…){…}
n C(…) : A(…) {…}
n C(…) : B(…) {…}
n C(…) : A(…),B(…) {…}
n C(…) : B(…),A(…) {…}
93

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 21
class A {
public:
A() {
cout << "Je suis A()" << endl;
}
A(int i, int j) {
cout << "Je suis A(int,int)" << endl;
Exercice
}
A(int i, int j, int k) {
cout << "Je suis A(int,int,int)" << endl;
}
};
int main() {
class B {
public:
B() { C c1;
cout << "Je suis B()" << endl;
}
C c2(1);
B(int i, int j) { C c3(1,1);
cout << "Je suis B(int,int)" << endl;
} C c4(1,1,1);
B(int i, int j, int k) {
cout << "Je suis B(int,int,int)" << endl;
} return 0;
}; }
class C : public A, public B{
public:
C() : B(1,1,1) {
cout << "Je suis C()" << endl;
}
C(int i, int j=1) : A(1,1,1) {
cout << "Je suis C(int,int)" << endl;
}
C(int i, int j, int k) : A (1,1) {
cout << "Je suis C(int,int,int)" << endl; 94
B ();
ENSA
ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 22
} COURS DE PROGRAMMATION EN C++ 2019-2020
POLYMORPHISME

¤ Le polymorphisme est un moyen de manipuler des objets hétéroclites de la même


manière, pourvu qu’ils disposent d’une interface commune.

¤ Un objet polymorphe est un objet susceptible de prendre plusieurs formes pendant


l’exécution.

¤ Le polymorphisme représente la capacité du système à choisir dynamiquement la


méthode qui correspond au type de l’objet en cours de manipulation.

¤ Le polymorphisme est implémenté en C++ avec les fonctions virtuelles (virtual) et


l’héritage.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 23
LE COMPORTEMENT NON POLYMORPHE

¤ Considérons les classes suivantes

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 24
LE COMPORTEMENT NON POLYMORPHE

¤ Créons une fonction supplémentaire qui reçoit en paramètre un Vehicule et modifions


le main()afin d'utiliser cette fonction :

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 25
LE COMPORTEMENT NON POLYMORPHE: EXPLICATION

¤ lors du passage dans la fonction, la vraie nature de la moto s'était perdue et qu'elle
était redevenue un simple véhicule.

¤ à l'intérieur de la fonction, on manipule un Vehicule. Peu importe sa vraie nature. Il va


donc appeler la « version Vehicule» de la méthode afficher()et pas la « version Moto»

¤ On est devant un cas de résolution statique des liens. La fonction reçoit un


Vehicule, c'est donc toujours la « version Vehicule» des méthodes qui sera utilisée.

¤ résolution statique des liens è C'est le type de la variable qui détermine quelle
fonction membre appeler et non sa vraie nature.

¤ Pour aider la méthode presenter à se comporter correctement il faut plutôt utiliser la


résolution dynamique des liens è Vérifier le type de l’objet au moment de
l’exécution.

¤ Pour faire cela, il faut :


> utiliser un pointeur ou une référence ;
> utiliser des méthodes virtuelles.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 26
LA MÉTHODE VIRTUAL

p Si une méthode d'une classe de base est


virtuelle, alors, en cas d'appel de cette
méthode sur un pointeur pointant sur un
objet d'une classe dérivée:
p Si la classe dérivée a implémenté la
méthode :
è C'est celle-ci qui sera exécutée.
p Si la classe dérivée n'a pas implémenté la
méthode :
è C'est la méthode de la classe de base qui
sera exécutée
98

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 27
LE BON COMPORTEMENT

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 28
POLYMORPHISME

p Ce terme désigne la capacité qu‘a une méthode


de s'adapter automatiquement a l'objet manipulé
p Regroupement d’objets dans des listes
hétérogène.
p Soit une application de gestion de parc de véhicules:
n Classe VEHICULE, dérivée en MOTO, AUTO, CAMION
n Ces 4 classes ont une méthode Afficher()
n On mémorise dans une liste d'objets de type VEHICULE tous
les véhicules du parc (liste hétérogène)
VEHICULE v[10];
n Si on applique la méthode Afficher() a chaque objet de la liste,
on veut exécuter la méthode associée a l'objet (MOTO, AUTO
ou CAMION), et non pas la méthode générique de la classe
VEHICULE):
V[i].Afficher();
95

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 29
EXERCICE

class Vehicule {
public: int main () {
void afficher() { std::cout << "Je suis un Vehicule" << endl; }
Vehicule* v[4];
}; v[0] = new Vehicule();
v[1] = new Auto();
class Moto : public Vehicule { v[2] = new Moto();
public: v[3] = new Camion();
void afficher() { std::cout << "Je suis une Moto" << endl; } Moto* p1 = new Moto();
Auto* p2 = new Auto();
};
Camion* p3 = new Camion();

class Auto : public Vehicule { v[0]->afficher();


public: v[1]->afficher();
void afficher() { std::cout << "Je suis un Auto" << endl; } v[2]->afficher();
}; v[3]->afficher();
p1->afficher();
p2->afficher();
class Camion : public Vehicule { p3->afficher();
public:
void afficher() { std::cout << "Je suis un Camion" << endl; } return 0;
}; }

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 30
SOLUTION A CE PROBLÈME

class Vehicule {
public:
virtual void afficher() { std::cout << "Je suis un Vehicule" << endl; }
};

class Moto : public Vehicule {


public:
void afficher() { std::cout << "Je suis une Moto" << endl; }
};

class Auto : public Vehicule {


public:
void afficher() { std::cout << "Je suis un Auto" << endl; }
};

class Camion : public Vehicule {


public:
void afficher() { std::cout << "Je suis un Camion" << endl; }
};

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 31
POLYMORPHISME
Un objet héritant une méthode d'une classe parente peut réagir de façon différente à l'appel de
cette méthode.
ellipse.h cercle.h
class Ellipse #include “ellipse.h” main.cpp
{
#include " cercle.h"
public : class Cercle : public Ellipse
Ellipse(); {
Ellipse (float x, float y, float a, float b); public : int main() La fonction deplace() n’est pas
{ redéfinie dans la classe Cercle,
Ellipse(const Ellipse & e); Cercle();
Ellipse e(0, 0, 8.5, 10.2); appelle celle de Ellipse.
~Ellipse(); Cercle (float x, float y, float d);
~ Cercle(); e.deplace(-1, 1); La fonction affiche() est redéfinie
protected : public : e.affiche(); dans la classe Cercle, appelle celle
float m_cX, m_cY; virtual void affiche(); de Cercle.
float m_a, m_b; }; Cercle c(-2.5, 2.5, 7,4);
c.deplace(0.5, 1.5);
public : c. affiche();
void deplace(float dx, float dy); cercle.cpp Appelle la fonction affiche()
void zoom(float z); de la classe Ellipse.
#include “cercle.h” Ellipse *p1;
float surface();
virtual void affiche();
p1 = new Ellipse;
}; Cercle::Cercle() : public Ellipse() p1 ->affiche();
{
} Ellipse *p2; Si la fonction affiche() est
p2 = new Cercle; virtuelle et est redéfinie dans
Cercle::Cercle(float x, float y, float d) : p2->affiche(); la classe Cercle, appelle celle
ellipse.cpp public Ellipse( x, y, d, d)
de Cercle bien que le pointeur
{
#include <iostream.h>
return 0; soit de type Ellipse. C'est le
}
} mécanisme de polymorphisme
void Ellipse::affiche() d'héritage.
void Cercle::affiche()
{ {
std::cout << "Ellipse de grand axe " << m_a; std::cout << "Cercle de rayon ";
std ::cout << " et de petit axe " << m_b << "\n"; std::cout << m_a / 2 << "\n";
} }

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 32


CLASSE ABSTRAITE

p Une classe est dite abstraite si elle contient au


moins une fonction virtuelle pure.
p Une fonction membre est dite virtuelle pure
lorsqu’elle est déclarée de la façon suivante :
Virtual type nomMethode(paramètres) = 0;
p Une classe abstraite ne peut pas être instanciée :
on ne peut créer d’objet à partir d’une classe
abstraite.
p Il est obligatoire d’avoir une définition pour les
fonctions virtuelles pures au niveau des classes
dérivées

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 33
33
CLASSE ABSTRAITE: EXEMPLE

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 34
CLASSE ABSTRAITE

* 1
orchestre instrument de musique

instrument à corde instrument à vent

cuivres bois

piano violon contrebasse

tuba trompette hautbois

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 35


VARIABLES ET MÉTHODES STATIQUES

¤ Une variables statique est une variable commune de toutes les instances. On dit que
c’est une variable de classes.

¤ Déclaration: static int varStat;

¤ Définition: int CLASS::varStat = 0;

¤ Les variables statiques sont consommés directement via le nom de la classe.

¤ Déclaration d’une méthode statique : static void afficher(); // ne pas mettre statique
dans l’implementatin

¤ Une méthode statique est appelée directement via le nom de la classe.

¤ Les méthodes statiques ne nécessitent pas une instance.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 36
05 PATRONS ET AMIES

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL


LES PATRONS « TEMPLATE »

¤ Parmi les techniques pour améliorer la réutilisabilité des morceaux de code, nous
trouvons la notion de généricité.

¤ Cette notion permet d’écrire du code générique en paramétrant des fonctions et des
classes par un type de données.

¤ Un module générique n’est alors pas directement utilisable : c’est plutôt un modèle,
patron (template) de module qui sera «instancié » par les types de paramètres qu’il
accepte.

¤ Dans C++, grâce à la notion de patron de fonctions, il est possible de définir une famille
de fonctions paramétrées par un ou plusieurs types, et éventuellement des
expressions.

¤ D'une manière comparable, C++ permet de définir des "patrons de classes". Là encore,
il suffira d’écrire une seule fois la définition de la classe pour que le compilateur puisse
automatiquement l'adapter à différents types.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 38


PATRONS DE FONCTIONS

¤ Pour illustrer les patrons de fonctions, prenons


un exemple concret : une fonction min qui
accepte deux paramètres et qui renvoie la plus
petite des deux valeurs qui lui est fournie.

¤ On désire bénéficier de cette fonction pour


certains types simples disponibles en C++ (int,
char, float). Les notions que nous avons vu en
C++ jusqu’à maintenant ne nous permettent de
résoudre ce problème qu’avec une seule
solution.

¤ Cette solution est d’utiliser la surcharge et de


définir trois fonctions min, une pour chacun des
types considérés.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 39


PATRONS DE FONCTIONS

¤ Définition des fonctions min grâce à la surcharge: lors d’un appel à la fonction min, le
type des paramètres est alors considéré et l’implantation correspondante est
finalement appelée.

¤ Ceci présente cependant quelques inconvénients :


> La définition des 3 fonctions (perte de temps, source d’erreur) mène à des
instructions identiques, qui ne sont différenciées que par le type des variables
qu’elles manipulent.

> Si on souhaite étendre la définition de cette fonction à de nouveaux types, il faut


définir une nouvelle implantation de la fonction min par type considéré.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 40


PATRONS DE FONCTIONS

¤ Une autre solution est de définir une fonction template, c’est-à-dire générique.

¤ Cette définition définit en fait un patron de fonction, qui est instancié par un type de
données (ici le type T) pour produire une fonction par type manipulé.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 41


PATRONS DE FONCTIONS

¤ Définition de la fonction min générique : il n’est donc plus nécessaire de définir une
implementation par type de données.

¤ On définit donc bien plus qu’une fonction, on définit une méthode permettant d’obtenir
une certaine abstraction en s’affranchissant des problèmes de type.

¤ Il est possible de définir des fonctions template acceptant plusieurs types de données
en paramètre. Chaque paramètre désignant une classe est alors précédé du mot-clé
class, comme dans l’exemple : template <class T, class U> ....

¤ Chaque type de données paramètre d’une fonction template doit être utilisé dans la
définition de cette fonction.

¤ Pour que cette fonctionnalité soit disponible, les fonctions génériques doivent être
définies au début du programme ou dans des fichiers d’interface (fichiers .h).

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 42


CLASSE TEMPLATE : PATRON DE CLASSES

¤ Il est possible, comme pour les fonctions, de définir des classes template, c’est-à-dire
paramétrées par un type de données.

¤ Cette technique évite ainsi de définir plusieurs classes similaires pour décrire un même
concept appliqué à plusieurs types de données différents.

¤ Elle est largement utilisée pour définir tous les types de containers (comme les listes,
les tables, les piles, etc.), mais aussi des algorithmes génériques par exemple.

¤ La syntaxe permettant de définir une classe template est similaire à celle qui permet de
définir des fonctions template.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 43


CLASSE TEMPLATE : PATRON DE CLASSES

¤ Considérons la classe suivante:

¤ Lorsque nous procédons ainsi, nous


imposons que les coordonnées d'un point
soient de valeurs de type int.

¤ Si nous souhaitons disposer de points à


coordonnées d'un autre type (float, double,
long ...), nous devons définir une autre classe
en remplaçant simplement, dans la classe
précédente, le mot clé int par le nom de type
voulu.

¤ Ici encore, nous pouvons simplifier


considérablement les choses en définissant
un seul patron de classe de cette façon:

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 44


CLASSE TEMPLATE : PATRON DE CLASSES

¤ Comme dans le cas des patrons de fonctions, la mention template <class T> précise
que l'on a affaire à un patron (template) dans lequel apparaît un paramètre de type
nommé T ;

¤ La définition de notre patron de classes n'est pas encore complète puisqu'il y manque
la définition des fonctions membres, à savoir le constructeur point et la fonction
affiche().

¤ Pour ce faire, la démarche va légèrement différer selon que la fonction concernée est
en ligne ou non. Voici par exemple comment pourrait être défini notre constructeur en
ligne:

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 45


CLASSE TEMPLATE : PATRON DE CLASSES

¤ En revanche, lorsque la fonction est définie en dehors de la définition de la classe, il


est nécessaire de rappeler au compilateur :
> que, dans la définition de cette fonction, vont apparaître des paramètres de type ;
pour ce faire, on fournira à nouveau la liste de paramètre sous la forme: template
<class T>
> le nom du patron concerné. Par exemple, si nous définissons ainsi la fonction
affiche, son nom sera: point<T>::affiche ()

¤ En définitive, voici comment se présenterait l'en-tête de la fonction affiche si nous le


définissions ainsi en dehors de la classe :

¤ En toute rigueur, le rappel du paramètre T à la suite du nom de patron (point) est


redondant puisqu’il a déjà été spécifié dans la liste de paramètres suivant le mot clé
template.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 46


CLASSE TEMPLATE : PATRON DE CLASSES

¤ Voici ce que pourrait être finalement la définition de notre patron de classe point :

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 47


CLASSE TEMPLATE : PATRON DE CLASSES
Utilisation d’un patron de classes

¤ Comme pour les patrons de fonctions, l’instanciation de tels patrons est effectuée
automatiquement par le compilateur selon les déclarations rencontrées. Après avoir
créé ce patron, une déclaration telle que:
> point <int> a;

¤ conduit le compilateur à instancier la définition d'une classe point dans laquelle le


paramètre T prend la valeur int. Autrement dit, tout se passe comme si nous avions
fourni une définition complète de cette classe. Si nous déclarons :
> point <float> ad ;

¤ le compilateur instancie la définition d'une classe point dans laquelle le paramètre T


prend la valeur float, exactement comme si nous avions fourni une autre définition
complète de cette classe.

¤ Si nous avons besoin de fournir des arguments au constructeur, nous procéderons de


façon classique comme dans :
> point <int> a (3, 5) ;
> point <float> ad (1.5, 9.6) ;

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 48


FONCTIONS AMIES
Problème

¤ Comment faire pour qu’une fonction f() et/ou


une classe B puisse accéder aux données
membres privées d’une classe A ?
¤ Rendre publiques les données membres des
classes.
>Inconvénient: on perd leurs protections.
¤ Ajout de fonctions d’accès aux membres
privés.
> Inconvénient : temps d’exécution
pénalisant.
¤ Fonctions amies : Il est possible de déclarer
qu’une ou plusieurs fonctions (extérieurs à la
classe), sont des « amies » ; une telle
déclaration d’amitié les autorise alors à
accéder aux données privées au même titre
que n’importe quelle fonction membre.
> L’avantage de cette méthode est de
permettre le contrôle des accès au niveau
de la classe concernée.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 49


FONCTIONS AMIES
Exemple

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 50


FONCTIONS AMIES
Situation d’amitiés

¤ Fonction indépendante amie d’une classe.

¤ Fonction membre d’une classe amie d’une autre classe.

¤ Toutes les fonctions membres d’une classe, amies d’une autre classe.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 51


FONCTIONS AMIES
Situation d’amities à Exemple de fonction indépendante amie d’une classe

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 52


FONCTIONS AMIES
Situation d’amities à Fonction membre d’une classe amie d’une autre classe

¤ On considère deux classes A et


B

¤ int f(char, A) fonction membre


de B

¤ f doit pouvoir accéder aux


membres privés de A, elle sera
déclarée amie au sein de la
classe A :
> friend int B :: f(char, A) ;

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 53


FONCTIONS AMIES
Situation d’amities à Toutes les fonctions membres d’une classe, amie d’une
autre classe
¤ C’est une généralisation du
cas précédent. On pourrait
d’ailleurs effectuer autant de
déclarations d’amitié qu’il n’y
a de fonctions concernées.

¤ Mais il est plus simple


d’effectuer une déclaration
globale. Ainsi pour dire que
toutes les fonctions
membres de la classe B sont
amies de la classe A, on
placera, dans la classe A, la
déclaration : friend class B;

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL 54


06 LES EXCEPTIONS

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA KENITRA – UNIVERSITÉ IBN TOUFAIL


BESOIN

¤ Un programme peut rencontrer des “conditions exceptionnelles” qui risquent de


compromettre la poursuite de son exécution
¤ La détection d’un incident et son traitement dans les programmes importants doivent
se faire dans des parties différentes du code.

int *pint;
pint = new int;
If (pint == NULL) {
cout << “Manque de
mémoire pour pint” << endl;
exit(1);
}

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 56
EXCEPTIONS

¤ La solution moderne du problème : les exceptions.

¤ Elles permettent le découplage total de la détection d’une anomalie


(exception) de son traitement en s’affranchissant de la hiérarchie des appels.

¤ Une exception est une rupture de séquence déclenchée par une instruction
“throw” comportant une expression (objet) d’un type (classe) donné.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 57
GESTION DE L’EXCEPTION

¤ La gestion de l’exception se fait en deux étapes :

> Une erreur détectée va lever une exception (throw)

> Un gestionnaire va récupérer cette exception et la traiter


convenablement (catch)

¤ Pour pouvoir détecter les exceptions, les instructions


susceptibles de lever des exceptions sont incluses dans
un bloc spécifique (try)

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 58
GESTION DE L’EXCEPTION (2)

try
{
//code à tester
}
catch (…) {
//traitement des erreurs
}

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 59
GESTION DE L’EXCEPTION (3)

¤ Définition de l’exception
class exception_triviale {

};

¤ Utilisation et levée de l’exception



try {
int i = 0;
i--;
if (i < 0 || i > NMAX) {
exception_triviale e;
throw(e);
}

}

¤ Interception et traitement de l’exception


catch (exception_triviale e) {

}

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 60
PLUSIEURS CATCH

try
{
//code à tester
}
catch (Exception1 &e1) {
//traitement des erreurs
}
catch (Exception2 &e2) {
//traitement des erreurs
}
COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA
ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 61
THROW DANS LA DÉCLARATION D’UNE MÉTHODE

¤ Au lieu d’utiliser un bloc try…catch, il est possible de placer un throw sur toute la
méthode.

double myfunction (char param) throw (Exception);


double myfunction (char param) throw ();
double myfunction (char param) throw (Exc1,Exc2);

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 62
REPRISE DE L’EXÉCUTION

¤ Le modèle de gestion des exceptions proposé par C++ ne


permet pas de reprendre l’exécution à partir de
l’instruction ayant levé l’exception, mais le permet après
le bloc catch correspondant

¤ Si le bloc try/catch n’est pas prévu, l’exception


déclenchée par throw provoque l’arrêt de l’exécution dans
la fonction ou méthode courante.

¤ Le flot de contrôle peut être repris après le bloc “catch”

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 63
LES EXCEPTIONS STANDARD C++

¤ Les exceptions standard sont des classes dérivées d’une


classe de base exception

¤ Leur déclaration figure dans le fichier-entête stdexcept

¤ Certaines peuvent être déclenchées par des fonctions ou


des opérateurs de la bibliothèque standard

¤ Example : bad_alloc : échec d’allocation mémoire par


new

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 64
SPÉCIFICATION D’INTERFACE

¤ Une fonction peut spécifier les exceptions qu’elle est


susceptible de déclencher.
¤ Elle le fait à l’aide de throw placé juste après
l’identificateur de la fonction
¤ void f() throw (A,B){ …}
¤ // f est censée ne déclencher que les exceptions A et B
¤ Toute exception non prévue et déclenchée à l’intérieur de
la fonction (ou d’une fonction appelée) entraîne l’appel de
la fonction «unexpected »
¤ « unexpected » => terminate =>abort par défaut.

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 65
LES EXCEPTIONS STANDARD C++

La bibliothèque stadard (stdl) comporte quelques classes


qui dérivent de la classe de base exception
>Logic_error
+Domain_error
+Invalid_argument
+Length_error
+Out_of_range

>Runtime_error
+range_error
+overflow_error
+Underflow_error

>Bad_alloc //échec d’allocation mémoire par new


>Bad_cast //échec de l’opérateur dynamic_cast
>Bad_exception //erreur de spécification d’exception (peut être déclenché
par unexpected)
>Bad_typeid //echec de la fonction typeid

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 66
CRÉATION DES EXCEPTIONS DÉRIVÉES DE LA CLASSE EXCEPTION

¤ Raisons :

> Faciliter le traitement des exceptions : interception de toute


exception avec le simple gestionnaire :
catch (exception & e){…}
Cela est vérifié pour les exceptions dérivées de la classe
“exception”.

> Utiliser la fonction “what” de la classe exception, qui renvoie la


chaîne de caractères utilisée par le constructeur de l’exception

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 67
EXEMPLE DE LA FONCTION WHAT

#include <iostream.h>
#include <stdlib.h>
#include <stdexcept>

using namespace std;


int main(){
try{
throw range_error("anomalie_1");
}

catch (range_error &re){


cout << "exception: “ << re.what() << endl;

}
return 0;
}

¤ Résultats :
exception: anomalie_1

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 68
UN VRAI EXEMPLE D’UTILISATION DE « RANGE_ERROR »

¤ #include <iostream>
¤ #include <stdlib.h>
¤ #include <stdexcept>

¤ using namespace std;

¤
¤
int main(){
try{
Résultat
¤
¤
int i=100;
double epsilon=0.1;
d’exécution:
¤ double somme=0.0;
¤ for(int k=1; k<=100;k=k+10) somme courante10
¤ {
¤ epsilon=epsilon/k; somme courante120
¤ if (epsilon<=0.001)
¤ throw range_error("anomalie_1"); exception: anomalie_1
¤ else
¤ { Press any key to continue
¤ somme=somme+1/epsilon;
¤ cout<<"somme courante"<<somme<<endl;}
¤ }
¤ cout<<"somme = "<<somme<<endl;
¤ }
¤ catch (range_error &re){
¤ cout<<"exception: "<<re.what()<<endl;
¤ }
¤ }

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 69
UTILISATION DE L’EXCEPTION BAD_ALLOC

¤ #include "stdafx.h"
¤
¤
#include <iostream>
#include <stdlib.h>
Exception d'allocation de
¤
¤
#include <stdexcept>
#define MAX_NUMBER 1000000000
mémoire par new
¤ using namespace std; Vous êtes trop gourmand!
¤ int _tmain(int argc, _TCHAR* argv[]) bad allocation
¤ {
¤ try Press any key to continue
¤ {
¤ int* ptrTab;
¤ for (int i=0;i<MAX_NUMBER; i++)
¤ ptrTab=new int[MAX_NUMBER];
¤ }
¤ catch (bad_alloc & b) l’exception « bad-alloc »
{
¤
¤ cout<<"Exception d'allocation de mémoire par new"<<endl; est déclenchée par la
¤
¤
cout<<"Vous êtes trop gourmand!"
<<endl<<b.what()<<endl;
fonction « new » de la
¤
¤
}
return 0;
librairie standard.
¤ }

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 70
EXCEPTIONS

définir ses propres classes par héritage

class myException : public std::exception


{
// redéfinir la méthode what();
};

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 71
HÉRITAGE DE LA CLASSE EXCEPTION

#include <iostream> void main(void) {


#include <stdexcept>
using namespace std; try {
class monException1 : public exception { cout << "Bloc try 1" << endl;
public: throw monException1();
monException1() {} }
// Surcharge de la méthode virtuelle what catch (exception& e) {
virtual const char* what() const cout << "Exception : " << e.what() <<
{ endl;
return "Mon exception no 1"; } }
}; try {
class monException2 : public exception { cout << "Bloc try 2" << endl;
public: throw monException2("deuxieme type");
monException2(char* texte) { this->texte = }
texte; } catch (exception& e) {
cout << "Exception : " << e.what() << endl;
// Surcharge de la méthode virtuelle what }
virtual const char* what() const { return texte; } }
private:
char* texte;
};

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 72
07 > NAMESAPCE
ESPACES DE NOMMAGE

73
ESPACES DE NOMMAGE

¤ Un espace de noms, c'est quelque chose qui regroupe des variables


et des fonctions, des classes, tout ce que vous voulez dans un même
ensemble.
¤ Pour éviter les ambiguïtés lors du nommage de classes, de fonctions.
> définition de namespace
> utilisation d'un namespace pour consommer le contenu

#include <iostream>

using namespace std; //On utilise un espace de noms ici

const int valeur=5;

int main(int argc, char* argv[])


{
cout << "Valeur = " << valeur << endl;
return 0;
}
COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA
ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 74
ESPACES DE NOMMAGES

¤ Définir un namespace : attribuer un nom plus complet à une classe,


variable, fonction

¤ Syntaxe :

namespace nom
{
déclarations & définitions;
}

¤ Découpable en plusieurs morceaux


>.h, class, .cpp, ….

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 75
ESPACES DE NOMMAGES

¤ Utiliser un namespace :

¤ donner le nom complet de ce à quoi on veut accéder

¤ résolution de portée ::

nom_du_namespace::nom_à_accéder

ou

using namespace nom_du_namespace

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 76
ESPACES DE NOMMAGES

déclarer et définir / séparation .h/.cpp


dans le fichier .h

namespace mon_espace
{
class T
{
T();
~T();
long foo();
};
}

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 77
ESPACES DE NOMMAGES

dans le fichier cpp


mon_espace::T::T()
{}

mon_espace::T::~T()
{}

long mon_espace::T::foo()
{
return 0;
}

COURS DE PROGRAMMATION EN C++ 2019-2020 ENSA


ENSAKENITRA
KENITRA––UNIVERSITÉ
UNIVERSITÉIBN
IBNTOUFAIL
TOUFAIL 78

Vous aimerez peut-être aussi