Benoît DARTIES
ITC34 - Algorithmique et programmation
Partie C / C++
1
Le langage C++ : ajouts et spécificités
2
Benoît DartiesITC313 - Partie C / C++
Le type String
3
Type objet String‣ manipulation simplifiée et avancée des chaînes de caractères‣ utilisation de méthodes permettant traitements efficaces et simplifiés‣ obtention de la taille, contaténation, substitution de sous-chaînes‣ http://www.cplusplus.com/reference/string/string/
String a;
a = "darties"; // initialisation
cout << a << endl; // affichagecout << a.length() << endl; // obtention de la taillecout << a.at(4) << endl; // obtention du 4eme caractère
Benoît DartiesITC313 - Partie C / C++
Références
4
Référence sur variable‣ Mécanisme propre au C++ (inexistant en C)‣ Nommer une variables avec plusieurs identificateurs
- utilisation du caractère & avant identificateur de variable- référence associée à une variable lors de sa déclaration- référence fixe
‣ Multiples références à l’intérieur d’une même fonction,‣ ou situées dans des fonctions différentes
‣ Permet de créer un alias sur une variable lors d’un appel de fonction
- pas de création d’ un nouvel élément dans la pile
Benoît DartiesITC313 - Partie C / C++
Références
5
#include <iostream>using namespace std;
int main() {int a = 10;int &b = a; // a et b désignent la meme variableint &c = b; // a, b et c désignent la meme variableint &d; // erreur à la compilation !
a = a + 5;b = b + 10;c = c + 15;cout << "a = " << a << endl; // a = 40cout << "b = " << b << endl; // b = 40cout << "c = " << c << endl; // c = 40
}
Benoît DartiesITC313 - Partie C / C++
Références
6
#include <iostream>using namespace std;
void addition(int x, int y) { x = x + y;
}
int main() {int a = 10;int b = 30;
addition(a, 20);addition(a, b);
cout << "a = " << a << endl; // a = 10 NON MODIFIE}
Benoît DartiesITC313 - Partie C / C++
Références
7
#include <iostream>using namespace std;
void addition(int &x, int &y) { //référence sur variablesx = x + y;
}
int main() {int a = 10;int b = 30;
addition(a, 20);addition(a, b);
cout << "a = " << a << endl; // a = 60 : MODIFIE}
Benoît DartiesITC313 - Partie C / C++
Surcharge de fonctions
8
Signature d’une fonction : ‣ en C : identificateur
- Impossible d’avoir le même identificateur de fonction
‣ en C++ : identificateur + liste des paramètres➡ le type de la fonction n’est pas dans la signature
Surcharge de fonction‣ Possibilité d’avoir plusieurs fonctions ayant le même identificateur si
ces derniers ont des paramètres différents
Benoît DartiesITC313 - Partie C / C++
Surcharge de fonctions
Exemple :
9
int addition (int nb1, int nb2) {return nb1 + nb2;
}
float addition (float nb1, float nb2) {return nb1 + nb2;
}
int addition (int nb1, int nb2, int nb3) {return nb1 + nb2;
}
int addition (float nb1, float nb2) {return nb1 + nb2;
}
invalide en Cvalide en C++
invalide en Cvalide en C++
invalide en Cinvalide en C++même signature
Benoît DartiesITC313 - Partie C / C++
Opérateur de résolution de portée
Opérateur représenté par ::‣ Résolution des ambiguïtés‣ Spécifique au C++‣ Permet de distinguer les variables locales / globales‣ Appel de méthodes statiques propres à une classe donnée
10
int i=5; // variable globale i
int main() {int i=0; // variable locale i
i++; // la variable locale i est incrémentée::i++; // la variable globale i est incrémentée
}
Benoît DartiesITC313 - Partie C / C++
Généricité paramétrique
11
Intérêt de la généricité paramétrique :‣ Possibilité d’énoncer des descriptions de fonctions‣ Certains éléments restent formels‣ Eléments vus comme des paramètres‣ Indéfinis dans la définition de la fonction‣ Par la suite, correspondance à :
- un type- un objet- une fonction- ou une valeur
Vocabulaire associé‣ Modèle de fonctions‣ Template en dialecte C++‣ polymorphisme paramétrique
Benoît DartiesITC313 - Partie C / C++
Généricité paramétrique
12
Fonction affichant un tableau d’entiers
Fonction affichant un tableau de caractères ?Fonction affichant un tableau de flottants ?Fonction affichant un tableau de booléens ?..
void afficheTab(int T[], int taille) {int i;int elementCourant;for (i = 0; i < taille ; i++ ) {
elementCourant = T[i];cout << elementCourant << ‘ ‘ ;
}}
Benoît DartiesITC313 - Partie C / C++
Généricité paramétrique
13
Création d’un paramètre formel identifiant un type de variables‣ Déclaration d’un type non défini «a priori»‣ Besoin d’un identificateur‣ mot-clé template < ... >‣ portée limitée au bloc immédiatement consécutif à la déclaration
template< typename monTypeFormel >
déclaration d’un paramètre formel :mot-clé template
ce paramètre formel sera un type :
mot-clé typename
Identificateur du type formel.
ici : monTypeFormel
Benoît DartiesITC313 - Partie C / C++
Généricité paramétrique
14
Création d’un paramètre formel identifiant un type de variables‣ Déclaration d’un type non défini «a priori»‣ Besoin d’un identificateur‣ mot-clé template < ... >‣ portée limitée au bloc immédiatement consécutif à la déclaration
template< typename monTypeFormel >
void afficheTab(monTypeFormel T[], int taille) {int i;monTypeFormel elementCourant;for (i = 0; i < taille ; i++ ) {
elementCourant = T[i];cout << elementCourant << ‘ ‘ ;
}cout << endl;
}
déclaration d’un paramètre formel :mot-clé template
Utilisation du type formel , ajout d’un niveau
d’abstraction supplémentaire
Benoît DartiesITC313 - Partie C / C++
Généricité paramétrique
15
Utilisation d’un modèle de fonctions‣ Modèle précédemment créé‣ Besoin d’informer le compilateur du(des) modèle(s) à utiliser‣ Lors de l’appel
- annonce du paramètre réel- correspond au paramètre formel de la déclaration
int main() {
int tab[5] = {1, 2, 3, 4, 5};afficheTab<int>(tab, 5);
float tab2[5] = {1.3, 2.2, 3.1, 4.4, 5.5};afficheTab<float>(tab, 5);
}
Précision de la valeur du paramètre formel
Précision de la valeur du paramètre formel
Benoît DartiesITC313 - Partie C / C++ 16
démo :
application sur les listes chaînées
Présentation de la programmation orientée objet
17
Benoît DartiesITC313 - Partie C / C++
Présentation
Programmation orientée objet ‣ paradigme de programmation informatique‣ définition et interaction d’objets
Un objet peut représenter :‣ une entité du monde physique‣ un concept‣ une idée
exemples d’objets :‣ Voiture, Personne, Véhicule, ...‣ Date, Couleur, Adresse, ...‣ Association, Relation, ...
18
Benoît DartiesITC313 - Partie C / C++
Présentation
Principe de l’encapsulation‣ Combinaison de données simples et de méthodes (assimilés fonctions)
dans une structure de données simple‣ Regroupement de toutes les composantes d’un objet‣ Interaction entre l’objet et l’environnement extérieur
- Programme- Autres objets
Définition formelle d’un objet :‣ Entité regroupant :
- des données membres : attributs - des fonctions membres : méthodes
➡ fonctions s’appliquant à l’objet ainsi qu’à ses attributs➡ fonctionnalités de l’objet➡ détermination de son comportement
19
Benoît DartiesITC313 - Partie C / C++
Définition d’un objet
Notion de classe‣ Définition formelle d’une famille d’objets‣ Définit les attributs et les méthodes de la famille d’objets‣ « Moule à objets »
Relation classe - objet‣ Objet défini par une classe : instance de la classe
Structure d’un programme orienté objet ‣ représentée par des schémas semi-formels : diagrammes‣ Modélisation conceptuelle ‣ Diverses méthodes de représentation : UML, Merise, ...
20
Benoît DartiesITC313 - Partie C / C++
Exemple : définition d’un jeu de combat spatial
21
Vaisseauid : chaîne de caractèretype : chaîne de caractèretaille : tableau de 3 entiersposition : tableau de 2 réels
naviguerVersCoords(réel, réel) : booléen
Identificateur de classe
Attributs
Méthodes
Exemple de classe
Nostromoid : "180924609"type : " transport CM88B"taille : (243, 164, 72)position : (45.4 ; 456.0)
MilleniumFalconid : "101141556263017875 05290188934432" type : "cargot YT-1300"taille : (34, 25, 8) position : (4.9 ; 587.0)
Pegasusid : "BSG-62"type : "Vaisseau de guerre"taille : (1414, 555, 177) position : (98.9 ; 457.5)
Exemple d’objets
Benoît DartiesITC313 - Partie C / C++
Spécificateurs d’accès
Eléments et visibilité :‣ Une classe peut posséder :
- des éléments (attributs / méthodes) accessible par le programme et n’importe quelles instance de classe
- des éléments qu’il ne souhaite pas accessibles depuis l’extérieur- des éléments dont l’accès doit être limité à un certain contexte
‣ définition de spécificateurs d’accès
Trois spécificateurs d’accès pour les attributs et méthodes :‣ public : accessibilité à partir de n’importe quelle instance de classe,
ou depuis n’importe quelle fonction du programme‣ private : accès restreint aux instances de la classe‣ protected : accès restreint aux instance de la classe ainsi qu’aux
instances de classe héritées (voir héritage)
22
Benoît DartiesITC313 - Partie C / C++
Le spécificateur d’accès public
Etiquette public :‣ Accès aux éléments de l’objet à l’intérieur et en dehors de ce dernier
Accès aux éléments déclarés public depuis l’objet‣ Annonce explicite de l’identificateur de l’élément
- nomAttribut- nomMethode()
Accès aux éléments déclarés public en dehors de l’objet‣ Annonce de l’objet ciblé, suivi d’un point, puis du nom de l’élément
- identificateurObjet.nomAttribut- identificateurObjet.nomMethode()
23
Benoît DartiesITC313 - Partie C / C++
Déclaration d’une classe
Déclaration d’une classe en C++‣ Syntaxe proche de la déclaration d’une structure en C‣ mot clé class
24
class nomClasse {
public : // spécificateur d’accès
// Liste des attributstype1 nomAttribut1;type2 nomAttribut2;...// Liste des méthodes : syntaxe similaire aux fonctionstype3 nomMethode1( ... ) { instructions ... }type3 nomMethode2( ... ) { instructions ... }
...};
Benoît DartiesITC313 - Partie C / C++
Déclaration d’une classe
Possibilité de déclarer les méthodes à l’extérieur d’une classe‣ inclusion du prototype dans la classe‣ hors classe :
- déclaration de la méthode, dite «déportée» (op. à «en ligne»)- précision de la classe à laquelle la méthode se rapporte- type nomClasse::nomMethode(...) { ...}
‣ Permet séparation en fichiers : structure (.h) et déclaration (.cpp)
25
class nomClasse {public : // spécificateur d’accès // Liste des méthodes : syntaxe similaire aux fonctionstype1 nomMethode1( ... ) ; // prototype
};
type1 nomClasse::nomMethode1( ... ) { //déclaration... // instructions
}
Benoît DartiesITC313 - Partie C / C++
Déclaration d’une classe
Exemple : déclaration de la classe Vaisseau
26
class Vaisseau {
public : // spécificateur d’accès// Liste des attributsString id;String type;int taille[3];int position[2];
// Liste des méthodes : syntaxe similaire aux fonctionsbool naviguerVersCoords(int x, int y) {
if ((x < 0) || (y < 0 )) return false;... // suite des instructions
}};
Benoît DartiesITC313 - Partie C / C++
Déclaration d’une méthode hors classe
27
class Vaisseau {public : // spécificateur d’accès// Liste des attributsString id;String type;int taille[3];float position[2];
// Prototypes des méthodes :bool naviguerVersCoords(float x, float y);
};
#include "Vaisseau.h"
// Liste des méthodes : syntaxe similaire aux fonctionsbool Vaisseau::naviguerVersCoords(float x, float y) {
if ((x < 0) || (y < 0 )) return false;... // suite des instructions
}
fichier Vaisseau.h
à inclure dans la com
pilationfichier V
aisseau.cpp
à inclure à l’édition de lien
Benoît DartiesITC313 - Partie C / C++
Création et manipulation d’un objet
Création d’un objet dans la pile‣ Type de l’objet : identifiant de la classe instanciée‣ Accès aux attributs / méthodes :
- nomObjet.nomAttribut ;- nomObjet.nomMethode() ;
28
#include "Vaisseau.h" //si la classe est dans autre fichier
int main() {Vaisseau Nostromo ;Vaisseau MilleniumFalcon;
Nostromo.id = "180924609";Nostromo.type = "transport CM88B";...Nostromo.naviguerVersCoords(450.0,567.0);
}
Benoît DartiesITC313 - Partie C / C++
Création d’un objet
Création d’un objet dans le tas‣ Utilisation d’un pointeur‣ Type du pointeur : identifiant de la classe instanciée suivi de *‣ Réservation de la mémoire : mot clé new suivi de l’identifiant de classe‣ Accès aux attributs / méthodes :
- identifiantObjet->identifiantAttribut ;- identifiantObjet->identifiantMethode() ;
29
int main() {
Vaisseau *MilleniumFalcon; // déclaration du pointeurMilleniumFalcon = new Vaisseau;
// accès aux attributs via un pointeurMilleniumFalcon->type = "Cargot YT-1300";
}
Benoît DartiesITC313 - Partie C / C++
Manipulation d’un objet par un pointeur
Manipulation d’un objet par un pointeur‣ Similaire à la manipulation de variables‣ Pointeur de type «identifiant de classe pointée» suivi de *‣ Adresse d’un objet : identificateur précédé de &‣ Accès aux attributs / méthodes :
- pointeurObjet->identifiantAttribut ;- pointeurObjet->identifiantMethode() ;
30
int main() {
Vaisseau MilleniumFalcon; // création du vaisseau (pile)Vaisseau *monPointeur ; // création du pointeur (pile)monPointeur = &MilleniumFalcon; // adressage// accès aux attributs via un pointeurmonPointeur->type = "Cargot YT-1300";
}
Benoît DartiesITC313 - Partie C / C++
Durée de vie d’un objet
Objet déclaré dans la pile‣ jusqu’à la fin du bloc d’instruction dans lequel est défini l’objet
Objet déclaré en zone de données statiques‣ durant toute l’exécution du programme
Objet déclaré dans le tas‣ jusqu’à libération de mémoire au moyen de l’instruction delete‣ fin du programme si pas de libération de mémoire
31
Vaisseau *Nostromo = new Vaisseau;...delete Nostromo;
Benoît DartiesITC313 - Partie C / C++
Surcharge de méthodes
Dans la déclaration d’une classe, surcharge de méthodes possible‣ signature d’une méthode : identificateur + liste des paramètres‣ même principe que la surcharge de fonctions‣ diffère de la redéfinition (voir plus loin)
32
class Vaisseau {...
// Prototypes des méthodes :bool naviguerVersCoords(int x, int y);bool naviguerVersCoords(float x, int y);bool naviguerVersCoords(int x, float y);bool naviguerVersCoords(float x, float y);
};
fichier Vaisseau.h
à inclure dans la com
pilation
Spécificateurs d’accès33
Benoît DartiesITC313 - Partie C / C++
Spécificateur public et restrictions
L’accès aux attributs public d’un objet :‣ Peut se faire depuis n’importe quel objet‣ De n’importe quel point d’exécution dans le programme‣ Problèmes de confidentialité / intégrité des données
- n’importe quel objet peut modifier les attributs d’un autre objet- n’importe quel objet peut exécuter les méthodes d’un autre objet
On souhaiterait pouvoir restreindre l’accès à certains éléments
- garantir l’intégrité de valeurs- affectation d’attributs «filtrée» par des garde-fous- ne pas pouvoir faire n’importe quoi
34
Benoît DartiesITC313 - Partie C / C++
Le spécificateur d’accès private
Etiquette private :‣ Accès aux éléments limité à l’intérieur de la classe‣ Si tentative d’accès en dehors de la déclaration de la classe :
- erreur à la compilation :
Attention : l’accès n’est pas exclusif à l’objet !‣ Accès exclusif à l’ensemble des objets de la classe :‣ un objet peut accéder aux paramètres privés d’un autre objet s’ils sont
de la même class (par exemple via une méthode dont un paramètre est un pointeur vers l’objet à modifier)
35
$ g++ programme.cpperror:l5: ‘ ... ‘ is privateerror:l20: within this context
Benoît DartiesITC313 - Partie C / C++
Utilisation des spécificateurs d’accès
Lors de la définition de la classe :‣ Annonce explicite du spécificateur d’accès, suivi de :‣ Application à tous les éléments déclarés à la suite du spécificateur
36
class nomClasse {private : // éléments ci-après déclarés private
type1 attribut1;type2 attribut2;...
public : // éléments ci-après déclarés public// Liste des constructeurs + méthodesnomClasse() { ... } nomClasse(type1 param1) { ... } ...type3 nomMethode1() { ... }
};
Benoît DartiesITC313 - Partie C / C++
Conséquences
37
class Vaisseau {private : // spécificateur d’accès private
// Liste des attributsString id;...
public : // spécificateur d’accès publicVaisseau() {
id = "-1";}
};
Vaisseau GloireDeLUnivers; // id positionné à -1
GloireDeLUnivers.id = "11111"; // écriture refusée
cout << "id: " << GloireDeLUnivers.id; // lecture refusée
main()
définition de la classe
Benoît DartiesITC313 - Partie C / C++
Le spécificateur d’accès private
Comment accéder aux éléments private hors de la classe?‣ Besoin d’accesseurs‣ Interface entre l’extérieur et la classe
- accesseurs en lecture ➡ méthode retournant la valeur d’un attribut
- accesseurs en écriture ➡ méthode affectant à un attribut une valeur en paramètre
‣ Méthodes généralement déclarées public‣ Possibilité de :
- restreindre l’accès en lecture ou écriture seulement- contrôler les valeurs affectées aux attributs
38
Benoît DartiesITC313 - Partie C / C++
Accesseurs en lecture / écriture
39
class Vaisseau {private : // spécificateur d’accès private
String id; // Attribut déclaré private...
public : // spécificateur d’accès publicString getId () { // accesseur en lecture sur id
return id; // retourne la valeur de id}
void setId( String p_id ) { // accesseur en ecritureif (p_id == "" ) // valeur vide interdite
id = "-1 ";else
id = p_id ;}...
};
définition de la classe
Benoît DartiesITC313 - Partie C / C++
Accesseurs en lecture / écriture
40
#include "Vaisseau.h"
int main() {
Vaisseau FhlostonParadise;
FhlostonParadise.id = "FP-255G"; // interdit
// mise à jour de l’id par l’accesseur en ecritureFhlostonParadise.setId ("FP-255G");
// affichage via l’accesseur en lecturecout << "id = " << FhlostonParadise.getId () << endl;
};
main()
Benoît DartiesITC313 - Partie C / C++
Le spécificateur d’accès protected
Accès à un attribut ou une méthode limité :‣ à l’intérieur d’une classe‣ ou a l’intérieur d’une sous-classe de la classe (classe fille, héritage)‣ hors d’une classe ou d’une sous-classe :
- comportement similaire à un attribut private- accès aux attributs protected via des accesseurs
41
Constructeurs et destructeurs42
Benoît DartiesITC313 - Partie C / C++
Notion de constructeur
Lors de l’instanciation d’une classe (création d’un objet)‣ Appel d’un constructeur‣ Rôle :
- initialisation de variables- appel de méthodes / routines d’initialisation- pré-traitements
‣ méthode particulière de la classe :
- Identificateur identique à celui de la classe- Paramètres possibles- Surcharge possible : plusieurs constructeurs- aucun type
43
class nomClasse {public : nomClasse() { instructions ... } // Constructeur...
};
Benoît DartiesITC313 - Partie C / C++
Constructeur de classe
Par défaut : aucun paramètre
44
class Vaisseau {public :
String id;int position[2];String type;
Vaisseau () {position[0]=0;position[1]=0;id =-1;...
} ...
};
Vaisseau Pegasus;
Appel automatique du constructeur sans paramètres à la création de l’objet. Attributs initialisés avec
valeurs par défaut
Benoît DartiesITC313 - Partie C / C++
Surcharge de constructeurs
Possibilité de définir plusieurs constructeurs
45
class nomClasse {
public : // Liste des constructeursnomClasse() { ... } nomClasse(type1 param1) { ... } nomClasse(type2 param2) { ... } nomClasse(type1 param1, type2 param2) { ... } ...
};
nomClasse monObjet1; // pile nomClasse monObjet2(valType1); // pile nomClasse monObjet3(valType1, valType2); // pile nomClasse *monObjet4 = new nomClasse(valType2); // tas nomClasse monObjet5(); // syntaxe incorrecte
main()
définition de la classe
Benoît DartiesITC313 - Partie C / C++
Surcharge de constructeurs
Possibilité de définir plusieurs constructeurs
46
class Vaisseau {...Vaisseau () { ... } // constructeur par défautVaisseau (String p_id) { // constructeur avec 1 param
position[0] = 0.0;position[1] = 0.0;id = p_id;...
} Vaisseau (String p_id, String p_type) {
type = p_type; id = p_id; ...
}};
Vaisseau Enterprise1("NCC-1701-D", "Croiseur Lourd"); Vaisseau *Enterprise2 = new Vaisseau("NCC-1701-D");
main()
définition de la classe
Benoît DartiesITC313 - Partie C / C++
Définition de constructeurs
Définition de constructeurs et constructeurs par défaut‣ Par défaut : existence d’un constructeur sans paramètres‣ Si définition d’un constructeur avec paramètres :
- disparition du constructeur par défaut‣ Redéfinition possible explicite du constructeur sans paramètres
47
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
Constructeur par copie (ou affectation)‣ Constructeur implicite‣ Appelé lors de duplication d’objets
- Affectation- Passage d’un objet en paramètres
‣ Copie les valeurs des attributs d’un objet vers un autre
48
nomClasse nomObjet1;nomClasse nomObjet2(nomObjet1); //constructeur par copienomClasse nomObjet3 = nomObjet1; // autre syntaxe
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
49
Nostromoid : "180924609"type : "transport CM88B"taille : (243, 164, 72)position : (45.4 ; 456.0)
Vaisseau Nostromo("180924609", "transport CM88B");Nostromo.setTaille(243, 164, 72);
Nostromo.naviguerVersCoords(45.5,456.0);
Vaisseau Copie = Nostromo;Vaisseau Copie2(Nostromo);
Copieid : "180924609"type : "transport CM88B"taille : (243, 164, 72)position : (45.4 ; 456.0)
Copie2id : "180924609"type : "transport CM88B"taille : (243, 164, 72)position : (45.4 ; 456.0)
Exemple de code :
Objets créés et valeur des attributs :
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
Constructeur par copie et attributs pointeurs‣ Attention :
- Attributs en tant que des pointeurs- Copie des adresses des objets pointés- Pas de création d’un nouvel élément !- Un pointeur dans chaque objet, pointant vers le même élément- Problèmes divers dans l’exécution du code si conception erronée
Possibilité de redéfinir le constructeur par copie‣ méthode : nomClasse(nomClasse) { ... }
50
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
Constructeur par copie et pointeurs‣ Utilisation du modèle de classe suivant :
- Création d’un classe Personne- Affectation d’un commandant à chaque vaisseau- Pointeur sur un objet de classe Personne
51
Vaisseauid : chaîne de caractèretype : chaîne de caractèretaille : tableau de 3 entiersposition : tableau de 2 réelscommandant : Personne *
naviguerVersCoords(réel, réel) : booléenaffecterCommandant (Personne *) : void
Personnenom : chaîne de caractèreprenom : chaîne de caractèregrade : chaîne de caractère
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
52
class Personne {private :
String nom;String prenom;
public :Personne (String p_prenom, String p_nom) {
nom = p_nom; prenome = p_prenom;}
};
class Vaisseau {...private :
Personne *commandant;public :
affecterCommandant (Personne * p_personne) {commandant = p_personne;
}};
classe Personneclasse Vaisseau
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
Constructeur par copie et pointeurs
53
Enterprise-Did : "N-1701-D"type : "Croiseur Lourd"...commandant :
JLPicardnom : "Picard"prenom : "Jean-Luc"...
#include "Personne.h"#include "Vaisseau.h"
int main () {Personne JLPicard("Jean-Luc", "Picard");Vaisseau Enterprise-D("N-1701-D","Croiseur Lourd");Enterprise-D.affecterCommandant(&JLPicard);Vaisseau Enterprise-E = Enterprise-D;
}
Enterprise-Eid : "N-1701-D"type : "Croiseur Lourd"...commandant :
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
Redéfinition du constructeur par copie
54
class Vaisseau {private :
Personne *commandant;...
public :Vaisseau(Vaisseau Original) {
id = Original.id;type = Original.type;if (Original.commandant !=NULL) {
Personne *clone;clone = new Personne(Original.commandant); // TAScommandant = clone;
}else commandant = NULL;
}};
Benoît DartiesITC313 - Partie C / C++
Constructeur par copie
Redéfinition du constructeur par copie
55
Enterprise-Did : "N-1701-D"type : "Croiseur Lourd"...commandant :
JLPicardnom : "Picard"prenom : "Jean-Luc"...
Enterprise-Eid : "N-1701-D"type : "Croiseur Lourd"...commandant :
Personne JLPicard("Jean-Luc", "Picard");Vaisseau Enterprise-D("N-1701-D","Croiseur Lourd");Enterprise-D.affecterCommandant(&JLPicard);Vaisseau Enterprise-E = Enterprise-D;
nom : "Picard"prenom : "Jean-Luc"...
Benoît DartiesITC313 - Partie C / C++
Destructeur
Quand un objet est-il détruit? ‣ Instanciation statique (pile) : fin du bloc d’instruction‣ Instanciation dynamique (tas) : libération par delete
- paramètre : adresse de l’objet (fournie par pointeur)
Note : delete sur objet situé dans la pile ?
‣ Compilation OK‣ Erreur à l’exécution : pointeur invalide
56
Personne JLPicard("Jean-Luc", "Picard"); // piledelete &JLPicard;
Benoît DartiesITC313 - Partie C / C++
Destructeur
Qu’est-ce qu’un destructeur ?‣ Méthode appelée sur un objet lors de la destruction de ce dernier‣ Libère la mémoire utilisée par l’objet
Redéfinition du destructeur possible ‣ Pourquoi redéfinir le destructeur ?
- libérer la mémoire des objets du tas dont l’unique pointeur est situé dans l’objet (cf ex. précédant)
- Tâches de post-traitement- Messages / log / debug ..
‣ Nom de la méthode à redéfinir : ~nomClasse()
- pas de paramètres ! Erreur compilation sinon- surcharge impossible! Erreur compilation sinon
➡ n’aurait pas de sens
57
Benoît DartiesITC313 - Partie C / C++
Destructeur
Sans redéfinition :
58
Enterprise-Did : "N-1701-D"type : "Croiseur Lourd"...commandant :
JLPicardnom : "Picard"prenom : "Jean-Luc"...
Enterprise-Eid : "N-1701-D"type : "Croiseur Lourd"...commandant :
Personne JLPicard("Jean-Luc", "Picard");Vaisseau Enterprise-D("N-1701-D","Croiseur Lourd");Enterprise-D.affecterCommandant(&JLPicard);Vaisseau Enterprise-E = Enterprise-D;delete Enterprise-E;
nom : "Picard"prenom : "Jean-Luc"...
Mémoire toujours réservée mais
désormais inaccessible
Benoît DartiesITC313 - Partie C / C++
Redéfinition du destructeur
Redéfinition du destructeur‣ exemple : élimination du commandant si Vaisseau détruit
59
class Vaisseau {private :
Personne *commandant;...
public :~Vaisseau() {
if (commandant != NULL) {delete commandant;
}}
};
Surcharge d’opérateurs60
Benoît DartiesITC313 - Partie C / C++
Mécanismes des opérateurs
Les opérateurs‣ Définissent une opération‣ Utilise des opérandes
- opérateurs unaires : une opérande- opérateurs binaires : deux opérandes
Mécanismes internes du compilateur‣ utilisation d’un opérateur :
- appel d’une fonction particulière - dont les opérandes sont les paramètres
61
Benoît DartiesITC313 - Partie C / C++
Mécanismes des opérateurs
opérateurs binaires : A OP B ‣ OP est l’opérateur‣ A est l’opérande de gauche‣ B est l’opérande de droite‣ se traduit par l’appel à la fonction operatorOP(A, B);
opérateurs unaire : OP A ‣ OP est l’opérateur‣ A est l’opérande ‣ se traduit par l’appel à la fonction operatorOP(A);
62
Benoît DartiesITC313 - Partie C / C++
Mécanismes des opérateurs
Exemple :
63
int main() { int a;int b;a = 5; // => appel a la fonction operator=(a, 5);b = a; // => appel a la fonction operator=(b, a);a + 10; // => appel a la fonction operator+(a, 5);
/* question : peut on directement appeler les fonctions : operator=(a, 5); operator=(b, a); operator+(a, 10);
reponse : non */}
Benoît DartiesITC313 - Partie C / C++
Surcharge d’opérateurs
Surcharge d’opérateur sur classes‣ Redéfinir un opérateur afin d’adopter une opération qui n’était pas
définie jusqu’à présent‣ Redéfinir le comportement d’un opérateur déjà existant‣ Deux modes de redéfinition :
- à l’extérieur de la classe- à l’intérieur de la classe
‣ Certains opérateurs ne peuvent être surchargés
64
Benoît DartiesITC313 - Partie C / C++
Surcharge d’opérateurs
Intérêt de la surcharge d’un opérateur
65
int main() { Vaisseau Cyberlab;Cyberlab.setId("999");Cyberlab.setType("Exploration");
cout << Cyberlab; // indéfini !
Cyberlab++; // indéfini !
++Cyberlab; // indéfini !
Cyberlab+=5; // indéfini !
Opérateur binaire <<opérande gauche : ostream &opérande droite : Vaisseau &
Opérateur unaire ++opérande gauche : Vaisseau &
Opérateur binaire +=opérande gauche : Vaisseau &
opérande droite : int
Opérateur unaire ++opérande droite : Vaisseau &
Benoît DartiesITC313 - Partie C / C++
Surcharge d’opérateurs
Surcharge d’un opérateur A OP B (à l’extérieur de la classe)‣ Surcharge de la fonction operatorOP(typeA &A,typeB &B)
66
Vaisseau Cyberlab;Cyberlab += 5;// on souhaite augmenter l’attribut nbPassagers avec +=
redéfinition de la fonction :
void operator+=(Vaisseau &V, int a) {int newNbpassagers = V.getNbPassagers();newNbpassagers = newNbpassagers + a;V.setNbPassagers(newNbpassagers);
}
Opérateur binaire +=opérande gauche : Vaisseau &
opérande droite : int
Benoît DartiesITC313 - Partie C / C++
Surcharge d’opérateurs
Surcharge d’un opérateur A OP B (à l’extérieur de la classe)‣ Surcharge de la fonction operatorOP(typeA &A,typeB &B)
67
Vaisseau Cyberlab;cout << Cyberlab;// on souhaite afficher les caractéristiques de Cyberlab
redéfinition de la fonction :
ostream & operator<<(ostream &o, Vaisseau &V) {o << "ID : " << V.getId() << "type : " << V.getType();return o; // necessaire pour concaténation de flux
}
Opérateur binaire <<opérande gauche : ostream &opérande droite : Vaisseau &
Benoît DartiesITC313 - Partie C / C++
Surcharge d’opérateurs
Liste non exhaustive d’opérateurs à surcharger
68
bool operator==(Vaisseau &V1, Vaisseau &V2) {...}bool operator<=(Vaisseau &V1, Vaisseau &V2) {...}bool operator>=(Vaisseau &V1, Vaisseau &V2) {...}bool operator<(Vaisseau &V1, Vaisseau &V2) {...}bool operator>(Vaisseau &V1, Vaisseau &V2) {...}bool operator=(Vaisseau &V1, Vaisseau &V2) {...}int operator++(Vaisseau &V1) {...}int operator++(Vaisseau &V1, int a) {...}int operator--(Vaisseau &V1) {...}int operator--(Vaisseau &V1, int a) {...}istream & operator>>(istream &i, Vaisseau &V) {...}...
Top Related