Chapitre 14. Construction, destruction, initialisation et recopie

Documents pareils
INFO-F-105 Language de programmation I Séance VI

1.6- Génération de nombres aléatoires

et Programmation Objet

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

C++ Programmer. en langage. 8 e édition. Avec une intro aux design patterns et une annexe sur la norme C++11. Claude Delannoy

Chapitre 2. Classes et objets

Introduction au pricing d option en finance

Programme Compte bancaire (code)

Programmation C++ (débutant)/instructions for, while et do...while

Le langage C++ (partie I)

Cours d initiation à la programmation en C++ Johann Cuenin

Cours de Programmation Impérative: Zones de mémoires et pointeurs

30.avr.10 Présentation miniprojet. 9.mars.10 Cours 3 4.mai.10 Cours C mars.10 Cours 4 11.mai.10 Cours C++ 2

Claude Delannoy. 3 e édition C++

Bases de programmation. Cours 5. Structurer les données

Le prototype de la fonction main()

Premiers Pas en Programmation Objet : les Classes et les Objets

Introduction à l héritage en C++

I. Introduction aux fonctions : les fonctions standards

Le langage C. Séance n 4

Cours d Algorithmique et de Langage C v 3.0

LE LANGAGE C++ ENAC 1997 A. DANCEL

as Architecture des Systèmes d Information

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Département Automatisation et Informatisation Année Programmation en C++ Institut des Sciences et Techniques de l Ingénieur d Angers

Généralités sur le Langage Java et éléments syntaxiques.

Programmation en C/C++

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Conventions d écriture et outils de mise au point

Les structures. Chapitre 3

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Plan Pédagogique du cours

ETUDE DE CAS en UML : GESTION DES COMMANDES DE PIECES FABRIQUEES PAR LA SOCIETE C

Java Licence Professionnelle CISII,


Programmation stochastique

C++ COURS N 2 : CLASSES, DONNÉES ET FONCTIONS MEMBRES Classes et objets en C++ Membres d'une classe Spécification d'une classe Codage du comportement

Exercices INF5171 : série #3 (Automne 2012)

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

Compression de Données - Algorithme de Huffman Document de Conception

TD3: tableaux avancées, première classe et chaînes

Travaux Dirigés n 1 : chaînes de caractères

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Programmation système I Les entrées/sorties

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Introduction au langage C

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Cours 1: Java et les objets

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Langage Java. Classe de première SI

École Polytechnique de Montréal. Département de Génie Informatique et Génie Logiciel. Cours INF2610. Contrôle périodique.

Programmation système en C/C++

Introduction à C++ et à wxwidgets

OS Réseaux et Programmation Système - C5

INITIATION A LA PROGRAMMATION

Génie Logiciel I. Cours VI - Typage statique / dynamique, fonctions virtuelles et classes abstraites, flots d entrées / sorties, et string

IUT ANNECY Département Mesures Physiques Cours d informatique Initiation au langage C

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Examen d informatique première session 2004

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Introduction à l algorithmique et à la programmation M1102 CM n 3

Les structures de données. Rajae El Ouazzani

Chapitre 1 : La gestion dynamique de la mémoire

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

Les processus légers : threads. Système L3, /31

Programmation en Java IUT GEII (MC-II1) 1

3IS - Système d'exploitation linux - Programmation système

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Analyse de sécurité de logiciels système par typage statique

NIMEGUE V3. Fiche technique 3.07 : Sauvegarde / Restauration manuelle

Informatique III: Programmation en C++

Programmation VBA/Excel. Programmation VBA. Pierre BONNET. Masters SMaRT & GSI - Supervision Industrielle P. Bonnet

Initiation à JAVA et à la programmation objet.

Informatique I. Sciences et Technologies du Vivant (Semestre 1)

Algorithmique et Programmation, IMA

ACTIVITÉ DE PROGRAMMATION

SYSTÈME DE GESTION DE FICHIERS

Programmation Orientée Objet

Didacticiel Bases de programmation en C++

V- Manipulations de nombres en binaire

4. Groupement d objets

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

SYSTÈME DE GESTION DE FICHIERS SGF - DISQUE

Unix/Linux I. 1 ere année DUT. Université marne la vallée

Mon premier rpm. 7 juin Avant de commencer RPM URPMI RPMBUILD... 2

Cours Langage C/C++ Programmation modulaire

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

Transcription:

Chapitre 14 : Construction, destruction, initialisation et recopie 205 Chapitre 14 Construction, destruction, initialisation et recopie Chapitre 14 : Construction, destruction, initialisation et recopie 206 1. Les 4 outils de départ - Pour une classe quelconque, le C++ fournit par défaut : un constructeur sans argument (n'initialise rien) un constructeur de recopie un destructeur un opérateur d'affectation

Chapitre 14 : Construction, destruction, initialisation et recopie 207 2. Durée de vie d'un objet - Un objet a une vie Création Vie Mort - Création déclaration (objets statiques ou automatiques) new (objets dynamiques) - Mort fin de la portée (objets statiques ou automatiques) delete (objets dynamiques) Chapitre 14 : Construction, destruction, initialisation et recopie 208 3. Construction et destruction d'un objet - constructeur: appel automatique juste après la création de l'objet - destructeur: appel automatique juste avant la mort de l'objet - Le constructeur et le destructeur assurent que l'objet est dans un état cohérent. // etc. { // etc. compte C; compte D; Objets automatiques Appel du constructeur compte* Z = new compte; // etc. // etc. delete Z; // etc. Objet dynamique Appel du destructeur pour C & D Appel du destructeur pour Z

Chapitre 14 : Construction, destruction, initialisation et recopie 209 4. Affectation - Par défaut, affectation membre par membre. class compte { double actif; // etc. ; compte C(2855.20); compte B(450.3); B = C; // affectation. 2855.20 2855.20 450.3 Après affectation C B Chapitre 14 : Construction, destruction, initialisation et recopie 210 5. Constructeur de recopie - De la même manière que l'affectation (par défaut), le constructeur de recopie par défaut effectue la copie membre à membre de la source vers la destination. - Il est appelé dans trois situations: 5.1. Initialisation d'un objet - Création d'un nouvel objet initialisé comme étant une copie d'un objet existant: compte C(280.98); // constructeur de recopie: création de l'objet B // et son initialisation avec les données de C. compte B(C); - Ou bien // constructeur de recopie: création de l'objet B // et son initialisation avec les données de C. compte B = C;

Chapitre 14 : Construction, destruction, initialisation et recopie 211 - Attention : il faudra différencier entre recopie et affectation. compte B; // création de l'objet. B = C; // pas de recopie mais uniquement l'affectation // car l objet est déjà créé. 5.2. Paramètre passé par valeur - Transmission d'une valeur à une fonction compte C(290.77); double fonction(compte); double z = fonction(c); // passage par valeur de C. Chapitre 14 : Construction, destruction, initialisation et recopie 212 5.3. Retour de fonction par valeur compte C; compte fonction(int); compte fonction() { compte X; return X; // retour par valeur de X

Chapitre 14 : Construction, destruction, initialisation et recopie 213 5.4. Utilité d'un constructeur de recopie #include <iostream> class test { // on suppose que nous avons un ptr sur un seul élément. int *ptr; void alloc_test(){ if (ptr==null) { std::cerr << "allocation de la mémoire a échoué!\n"; exit(1); test(int d=1000) { ptr = new int(d); // allocation et initialisation. alloc_test(); ~test(){ delete ptr; // libération. void affiche() { std::cout << "valeur: " << *ptr << std::endl; ; Chapitre 14 : Construction, destruction, initialisation et recopie 214 int main() { // appel du constructeur // déclaration permise car par défaut: d=1000. test x; // appel du constructeur de recopie dans ce cas, par // défaut fourni par le langage, création de l'objet y // puis recopie membre à membre de x vers y. test y = x; y.affiche(); return 0; - Le constructeur de recopie par défaut va effectuer une copie membre à membre. - Copier membre à membre un pointeur signifie que ptr de l'objet y pointe au même endroit que ptr de l'objet x (une recopie d'adresse). - À la fin du programme, le destructeur va être appelé pour détruire les objets x et y. - Détruire x revient à libérer la mémoire allouée pour le pointeur ptr de x. - Détruire y revient à libérer la mémoire allouée pour le pointeur ptr de y. - Or, comme il a été mentionné précédemment, les deux pointeurs pointent le même endroit. De ce fait, le même endroit va être détruit deux fois!

Chapitre 14 : Construction, destruction, initialisation et recopie 215 - Or, on ne peut pas détruire successivement deux fois la même chose d'où lors, de l'exécution du programme, nous obtenons: Segmentation fault (core dumped) - C'est une erreur fatale, classique quand il y a violation de la mémoire. - Une tentative d'accéder à quelque chose qui n'existe pas. - Pour corriger cette erreur, il faut définir le constructeur de recopie afin de masquer le constructeur de recopie par défaut fourni par le langage et redéfinir le nôtre. Chapitre 14 : Construction, destruction, initialisation et recopie 216 5.5. Prototype du constructeur de recopie nom_classe (const nom_classe&); - porte le même nom que la classe. - accepte comme argument un objet du type de la classe dans laquelle il a été déclaré. Il est passé par référence et il est constant car l'objet ne sert que pour la recopie. - ne retourne rien (ne pas mettre void)

Chapitre 14 : Construction, destruction, initialisation et recopie 217 - Pour l'exemple du paragraphe 5.4: #include <iostream> class test { int *ptr; void alloc_test(){ if (ptr==null) { std::cerr << "allocation de la mémoire a échoué!\n"; exit(1); test(int d=1000) { ptr = new int(d); // allocation et initialisation. alloc_test(); test(const test& T) { ptr = new int(*t.ptr); alloc_test(); ~test(){ delete ptr; // libération. void affiche() { std::cout << "valeur: " << *ptr << std::endl; ; Chapitre 14 : Construction, destruction, initialisation et recopie 218 int main() { test x; test y = x; // appel du constructeur de recopie. y.affiche(); return 0; - Sortie: valeur: 1000 - Un constructeur de recopie par défaut, copie donc bit à bit une zone de mémoire dans une autre. On parle alors de copie superficielle. - Ceci est insuffisant en présence de pointeurs comme membres de données dans une classe. - Il faut alors allouer une nouvelle zone mémoire, on parle alors de copie profonde (allocation puis recopie).

Chapitre 14 : Construction, destruction, initialisation et recopie 219 6. Objet contenant un objet #include <iostream> class compte { double actif; compte(double d):actif(d){ void affiche(){ std::cout << "actif: " << actif << std::endl; ; class client { compte c; int nas; client(int m, double v):c(v),nas(m) { void affiche() { std::cout << "nas: " << nas << std::endl; c.affiche(); ; Chapitre 14 : Construction, destruction, initialisation et recopie 220 int main() { client A(231940,456.89); A.affiche(); return 0; - Sortie: nas: 231940 actif: 456.89 - Pour créer un client, il faut passer par le constructeur de client. Ce dernier doit appeler le constructeur de compte. - En premier, ce sont les membres «données» de compte qui sont initialisés puis ce sera le tour des autres membres "données" de client.

Chapitre 14 : Construction, destruction, initialisation et recopie 221 7. Classe canonique On appelle une classe canonique toute classe qui contient au moins les éléments suivants : - Au moins un constructeur régulier - Un constructeur de recopie - Un destructeur - Un opérateur d'affectation class bidon { // membres privés bidon( ); // un constructeur régulier bidon(const bidon&); //un constructeur de recopie ~bidon(); // un destructeur bidon &operator=(const bidon&); // opérateur d'affectation ; Il est conseillé de concevoir des classes canoniques afin de prévoir les cas où la classe dispose de pointeurs sur des parties dynamiques. Nous avons déjà étudié ces cas là, dans la première partie de ce chapitre. Dans ce qui suit, nous allons examiner ces mêmes cas pour l'opérateur d'affectation et l'intérêt d'en définir un dans une classe. Chapitre 14 : Construction, destruction, initialisation et recopie 222 8. Opérateur d'affectation = 8.1. Généralités Un constructeur de recopie est appelé dans 3 situations suivantes : - Lors de la création en même temps que l'initialisation de l'objet créé; - Passage de paramètres; - Retour d'un objet comme résultat de fonction. Chaque classe possède un opérateur d'affectation par défaut. L'affectation est superficielle comme la copie et consiste en une affectation (de surface) membre à membre. Ceci pose les mêmes problèmes que ceux posés par le constructeur de recopie par défaut (voir les précédents paragraphes). Un opérateur d'affectation sert donc à l'affectation dans une expression et, retourne une référence. La signature de cet opérateur est comme suit : x& operator=(x) Ceci est équivalent d'écrire : y=x ou bien y.operator=(x)

Chapitre 14 : Construction, destruction, initialisation et recopie 223 Le résultat de l'affectation est dans l'objet appelant. L'opérateur d'affectation doit être une fonction membre. 8.2. Exemple d'une classe tableau #include <iostream> using namespace std; class tableau { int n; // la taille du tableau tab double *tab; // pointeur vers un tableau de double void alloc_test(){ // test d'allocation mémoire if (tab==null) { cerr << "allocation de la mémoire a échoué!\n"; exit(1); // test la taille du tableau void index_test(int taille_entree){ if (taille_entree<1) { cerr << "taille du tableau à allouer est inférieure\ ou égale à zéro! \n"; exit(1); Chapitre 14 : Construction, destruction, initialisation et recopie 224 // recopie élément par élément void recopie_elt(const tableau& T) { for (int i=0;i<n;i++) tab[i] = T.tab[i]; // constructeur tableau(int x) { index_test(x); tab = new double[n=x]; // allocation alloc_test(); // constructeur de recopie tableau(const tableau& T) { tab = new double[n=t.n]; alloc_test(); recopie_elt(t); // opérateur d'affectation tableau& operator=(const tableau& T) { // on teste si on n'affecte pas l'objet à lui-même. if (this!= &T) { delete [] tab; // on détruit les éléments déjà alloués. // on alloue de la mémoire à nouveau. tab = new double[n=t.n]; alloc_test(); // test d'allocation. recopie_elt(t); // recopie des éléments de T.tab à tab. return (*this); // on retourne l'objet appelant.

Chapitre 14 : Construction, destruction, initialisation et recopie 225 // initialise tous les éléments de tab à nbre. void init_tab (double nbre){ for (int i=0;i<n;i++) tab[i] = nbre; // destructeur ~tableau(){ delete [] tab; // libération. // affichage vers la sortie de tab. void affiche () { for (int i=0;i<n;i++) cout << "tab[" << i << "] " << tab[i] << endl; ; Chapitre 14 : Construction, destruction, initialisation et recopie 226 int main() { tableau a(3); // on crée un tableau de 3 éléments. a.init_tab(10.5); // on initialise tous ses éléments à 10.5 cout << "on affiche a...\n"; a.affiche(); // on affiche le contenu de a. // on crée un second tableau b de taille 2 (éléments) tableau b(2); // affectation de a vers b. Suite à l'utilisation de // operator= la taille de b devient égale à 3. b = a; cout << "le tour de b=a...\n"; b.affiche(); // on affiche b. return 0;

Chapitre 14 : Construction, destruction, initialisation et recopie 227 En sortie: on affiche a... tab[0] 10.5 tab[1] 10.5 tab[2] 10.5 le tour de b=a... tab[0] 10.5 tab[1] 10.5 tab[2] 10.5 Chapitre 14 : Construction, destruction, initialisation et recopie 228