2.2- Déclarer, définir et utiliser des objets

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

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

Chapitre 2. Classes et objets

Premiers Pas en Programmation Objet : les Classes et les Objets

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

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

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

Programmation par les Objets en Java

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

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

Héritage presque multiple en Java (1/2)

Chapitre 1 : Introduction aux bases de données

Tp 1 correction. Structures de données (IF2)

et Programmation Objet

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

I. Introduction aux fonctions : les fonctions standards

Les chaînes de caractères

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

Application 1- VBA : Test de comportements d'investissements

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

TD/TP PAC - Programmation n 3

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

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

Algorithmique et Programmation, IMA

Trier les ventes (sales order) avec Vtiger CRM

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

1. Étape: Activer le contrôle du compte utilisateur

Systeme d'exploitation


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

Java Licence Professionnelle CISII,

TD/TP PAC - Programmation n 3

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

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

Initiation à JAVA et à la programmation objet.

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

TP1 : Initiation à Java et Eclipse

Utilisation d objets : String et ArrayList

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

2 Grad Info Soir Langage C++ Juin Projet BANQUE

Diagramme de classes

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

1. Introduction Création d'une macro autonome Exécuter la macro pas à pas Modifier une macro... 5

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

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

La sauvegarde (backup) de votre comptabilité a pour but de vous permettre de retrouver vos données si un incident est survenu.

Langage Java. Classe de première SI

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

Projet gestion d'objets dupliqués

TP Composants Java ME - Java EE. Le serveur GereCompteBancaireServlet

JAVA TD0. Prise en main du langage Environnement de base JAVA 1

B2i. LE B2i Brevet Informatique et Internet. Niveau : tous. 1 S'approprier un environnement informatique de travail. b2ico1.odt.

RMI le langage Java XII-1 JMF

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

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

La programmation des PIC en C. Les fonctions, les interruptions.

TP1. Outils Java Eléments de correction

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

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

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

Le stockage local de données en HTML5

UE Programmation Impérative Licence 2ème Année

Introduction à l héritage en C++

Fichiers, dossiers, enregistrer et arborescence

Suite dossier d appel

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Plan Pédagogique du cours

Programmer en JAVA. par Tama

1. Qu'est-ce que SQL? La maintenance des bases de données Les manipulations des bases de données... 5

Cours 14 Les fichiers

1 sur 5 10/06/14 13:10

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

TP SIN Programmation sur androïde Support : eclipse

Le langage C. Séance n 4

Cours 1: Java et les objets

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

TP Service HTTP Serveur Apache Linux Debian

Conception d'applications de base de données ios plus rapides Guide Pratique FileMaker

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Cours Langage C/C++ Programmation modulaire

Cours d Algorithmique et de Langage C v 3.0

Claude Delannoy. 3 e édition C++

Traitement de texte : Quelques rappels de quelques notions de base

SOFI Gestion+ Version 5.4. Echanges de données informatiques Spicers Sofi gestion+ Groupements. SOFI Informatique. Actualisé le

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

Distinguer entre «Enregistrer» et «Sauvegarder»

Programmation Orientée Objet en C#

Débuter avec OOo Base

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

Bases Java - Eclipse / Netbeans

Chapitre 1 : La gestion dynamique de la mémoire

Connexion à une base de données. Connexion à une base de données. Connexion à une base de données Développement d'une application

Une introduction à Java

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence

COMMISSION DES NORMES COMPTABLES. Avis CNC 138/5 Logiciels

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

Transcription:

2.2- Déclarer, définir et utiliser des objets 1- Classes et objets 2- Construction d'objets 3- Destruction d'objets 1 Classes et objets A l'instar du fait de déclarer une fonction avant de l'utiliser, on déclare une classe avant de l'utiliser : on donne le prototype des méthode de ses classes ainsi que les variables de cette classe. Donc pour une classe, on doit distinguer : la déclaration de la classe qui donne les variables et les prototypes des fonctions de la classe. la définition des fonctions de classe. les utilisations de la classe. Bien sûr, avant de pouvoir définir des fonctions de classe ou avant de pouvoir utiliser une variable objet d'une classe, il faut avoir déclaré la classe. Déclaration de classe La déclaration se fait de la manière suivante : //on débute la déclaration de la classe Action //cette déclaration est comprise entre //un niveau de visibilité (voir plus bas) //la déclaration d'un attribut réel nommé coursdujour //la déclaration d'un attribut réel nommé coursancien //la déclaration d'une méthode renvoyant un double/prototype ; //la fin de la déclaration : bien noté qu'elle termine par ;

Ici on définit une classe Action qui donne le cours du jour, le coursancien et définit le calcul de la rentabilité. En définissant la classe de cette manière, et si le stockage d'un double représente bien 8 octets, alors le stockage d'un objet Action prendra 16 octets en mémoire. Autant que faire se peut, le nom retenu des variables/ attributs et des fonctions doit être significatif. Par ailleurs, par convention, on écrira le nom des classes avec une majuscule, le nom des attributs ou des méthodes, commençant à l'instar de ce qu'on a toujours fait pour les fonctions et les variables, par une minuscule et avec une majuscule dans le nom si il contient plusieurs mots : calcrentabilite par exemple. Bien noter que la déclaration d'une classe se termine par ';'. Les types des attributs de classe ne sont pas nécessairement des types primitifs, il peut y avoir des types objets : class Employe Date datenaissance; string nom; double salaire; Service serviceemploye; ; Dans ce qui précède, on a un attribut qui est un type primitif : double salaire, un attribut qui est d'un type objet de la librairie standard : string nom, deux attributs qui sont de types objets définis par l'utilisateur : Date, Service. Les déclarations de classe pourront bien sûr être faites dans un fichier header. Définition des méthodes de classe Une fois la déclaration de la classe faite, la définition des méthodes de classe peut se faire avant ou après leur utilisation. La déclaration d'une méthode de classe se fait en utilisant le nom de la classe, un séparateur et le nom de la méthode que l'on veut définir, ansi si on veut définir la méthode calcrentabilite() de la classe Action : double Action::calcRentabilite() return (coursdujour-coursancien)/ coursancien;

Pour le reste, le fonctionnement de la définition des fonctions est identique à ce qui a été déclarée au cours 1.4. Déclaration-définition d'une variable objet Un objet est une variable du type d'une classe. En supposant que des déclarations des classes Employe et Action ont été écrites dans le code qui précède, on peut déclarer des variables objets. Comme dans le cas des variables de type primitif, la déclaration des variables objets vaut également définition. La définition des variables de type objet se fait à l'instar des variables de type primitif : Action societegenerale; Accès aux données membres et aux fonctions membres #include <iostream> ; double Action::calcRentabilite() int main() Action societegenerale; societegenerale.coursdujour=5; societegenerale.coursancien=4.9; //L1 //L2 //L3 double variationenvaleur=societegenerale.coursdujour-societegenerale.coursancien; std::cout << "La rentabilite de l'action : " << societegenerale.calcrentabilite(); //L4 //L5 std::cout << "\nla taille : " << sizeof(action); //L6 return 0;

Dans ce qui précède, on commence par créer une variable objet de type Action qui a pour nom societegenerale (L1). Ensuite, on affecte 5 à la valeur de son attribut coursdujour (L2) puis on affecte 4.9 à son attribut coursancien (L3). Puis, on crée une variable de type primitif double à laquelle on affecte le résultat du calcul de la variation absolue du cours (L4). La ligne suivante est un appel la méthode calcrentabilite() de l'objet societegenerale (L5). La dernière ligne (L6) affiche la taille d'un objet Action. Pour cette dernière ligne, comme la classe Action a deux attributs de type double, le type Action sera deux fois la taille d'un type double, ie si une variable double occupe 8 octets, une variable Action sera codée sur 16 octets. Private / Public Dans l'exemple précédent, on peut prendre le code qui a été développé en enlevant cette ligne qui intervient dans la déclaration de la classe Action : En essayant de compiler le code obtenu, on obtient une série d'erreurs. Celles-ci indiquent que les éléments Action::coursDuJours, Action::coursAncien sont privées et que double Action::calcRentabilite() est privée. Les instructions qui posent problèmes sont celles qui sont dans le main() et qui tentent d'utiliser ces méthodes / attributs. Effectivement, si on ne précise plus que les attributs ou les méthodes sont public, ils sont tous private par défaut. Quand un attribut est private, il n'est utilisable qu'au sein des méthodes de la classe. On ne pourra donc l'utiliser que dans la définition des méthodes de classe. Pour déclarer comme public, on utilise le mot clé public à l'instar de ce qui a fait lors de la déclaration de la classe Action. De manière générale pour une classe pour laquelle il y a des attributs / méthodes de visibilité privée et des attributs / méthodes de visbilité #include <iostream> void affichagenumaction(); void affectationnumaction(int); private : int numaction; ;

double Action::calcRentabilite() void Action::affichageNumAction() std::cout << "Le numero de l'action : " << numaction; void Action::affectationNumAction(int num) numaction=num; int main() Action societegenerale; societegenerale.coursdujour=5; societegenerale.coursancien=4.9; societegenerale.affectationnumaction(3); double variationenvaleur=societegenerale.coursdujour-societegenerale.coursancien; std::cout << "La rentabilite de l'action : " << societegenerale.calcrentabilite(); std::cout << "\nla taille : " << sizeof(action) << "\n"; societegenerale.affichagenumaction(); return 0; Ce code fonctionne, il appelle un certain nombre de remaques : Toujours bien noter que la déclaration de classe se termine par un ; (tester ce qui se passe en l'enlevant) Pour une classe, il est possible de définir des attributs public et private. Dans la fonction donnenumaction, on manipule deux variables : le paramètre et un attribut de l'objet. Les attributs de l'objet peuvent être librement manipulé dans les méthode de l'objet Le code vérifie la règle énoncée plus haut qui est que les attributs privés (private) ne peuvent être manipulés que par des méthodes de l'objet. En effet, dans le main, on ne manipule pas l'attribut numaction. Si on essayait de le manipuler, on provoquera une erreur. Il est en revanche tout à fait possible de manipuler cet attibut via une méthode de la classe : on accède l'attribut dans la fonction affichagenumaction(), on aurait pu également lui affecter une valeur Quel est l'intérêt des niveaux de visbilité? Cf le fait de maintenir la cohérence externe de la classe. Le principe de la programmation objet veut qu'une classe soit réutilisable, soit par le même programmeur, soit par d'autres programmeurs. Il faut donc que les attributs de l'objet constituent un état cohérent de l'objet. Supposons que l'on rajoute un attribut dans la déclaration de la classe :

void affichagenumaction(); void affectationnumaction(int); private : int numaction; ; double Action::calcRentabilite() void Action::affichageNumAction() std::cout << "Le numero de l'action : " << numaction; void Action::affectationNumAction(int num) numaction=num; En effet, on veut que la valeur de la rentabilité soit stockée dans un attribut plutôt que recalculée à chaque fois qu'elle est accédée. A chaque appel de calcrentabilite() on recalculait la rentabilité, ici on préfère recalculer la rentabilité seulement si on modifie l'attribut coursdujour ou l'attribut coursancien. Celui qui conçoit la classe le sait ici et donc, si il modifie l'une ou l'autre des valeurs, il appel calcrentabilite() en faisant : societegenerale.coursdujour=5; double rentabilite=calcrentabilite(); Ensuite, on n'aura plus qu'à accéder directement la valeur de la rentabilité sans avoir à la recalculer. On peut vouloir cette optimisation, mais cependant, la forme actuelle de la classe est extrêmement dangereuse. Est ce que le programmeur ne risque pas à terme d'oublier l'instruction d'évolution de la rentabilité dès qu'il modifiera le coursdujour ou le coursancien? Plusieurs jours après construit cette classe avec cette contrainte, s'en souviendra t'il? Ne risque t'il pas d'oublier de parler de cette contrainte en donnant son code à un tiers qui veut utiliser la classe Action, le tiers parvenant rapidement à des abbérations dans l'utilisation de cette classe, si on ne lui a pas exposer les conditions d'utilisation. De fait, on préferera largement la version suivante de la classe :

void modifiercoursjour(double); double obtenircoursjour(); void modifiercoursancien(double); double obtenircoursancien(); double obtenirrentabilite(); void affichagenumaction(); void affectationnumaction(int); private : int numaction; ; double Action::calcRentabilite() void Action::affichageNumAction() std::cout << "Le numero de l'action : " << numaction; void Action::affectationNumAction(int num) numaction=num; void Action::modifierCoursJour(double x) coursdujour=x; rentabilite=calcrentabilite(); double Action::obtenirCoursJour() return coursdujour; void Action::modifierCoursAncien(double x) coursancien=x; rentabilite=calcrentabilite(); double Action::obtenirCoursAncien()

return coursancien; double Action::obtenirRentabilite() return rentabilite; Ici tous les attributs sont privés. Il n'est plus possible à un utilisateur externe à la classe de modifier ou de lire coursancien ou coursdujour directement. Pour voir la valeur de l'une ou l'autre des variables, il faut en passer par les méthodes : obtenircoursancien(), obtenircoursjour(). Pour modifier la valeur de l'une ou l'autre des variables, il faut en passer par les méthodes modifiercoursancien(double) pou modifiercoursjour(double). Pour ces deux dernières méthodes, on note qu'elles font évoluer la rentabilité. Donc à chaque fois qu'on modifie coursancien ou coursdujours, on modifiera la rentabilite. La classe sera donc maintenue dans un état cohérent. Pour les méthodes obtenircoursancien(), obtenircoursjour(), on parlera d'accesseurs (méthode qui permet d'accéder à la valeur d'un variable) et de modifieur (méthode qui permet de modifier la valeur d'une variable). On note que pour rentabilité, on a seulement défini un accesseur et pas de modifieur : on n'autorise pas la modification directe de l'attribut rentabilité. L'introduction de modifieurs ou d'accesseurs n'est pas une obligation, elle est cependant nécessaire dans la conception d'un grand projet pour maintenir la cohérence des objets. Pour les petits projets ou pour les exercices, il n'est bien sûr pas nécessaire d'introduire ces méthodes. On a donc conçu une classe de manière à maintenir la cohérence interne de la classe, des objets. Cependant, rien n'indique que chaque objet soit cohérent dès la déclaration d'une variable objet. On va donc s'intéresser à ce qui se passe lors de la déclaration des variables objets (et également lors de leur disparition) dans ce qui suit. 2 Construction d'objets Constructeur Il est possible de définir les opérations qui sont à faire lors de la création d'une variable objet. Cela se fait au travers d'une fonction qui s'appelle le constructeur. Sans l'évoquer, nous avons déjà utilisé implicitement une telle fonction. En reprenant le dernier listing de code qui a été présenté, on peut rajouter à la suite la ligne : int main() Action a;

Cette ligne de code, que l'on a déjà vu, sert à créer a comme une variable objet de type Action. Il s'agit d'un appel implicite à la fonction constructeur. C'est le seul cas d'appel à une méthode sans qu'il y ait de parenthèses. Lorsque le programmeur n'a pas défini de méthode constructeur, il existe une méthode constructeur par défaut : c'est le cas de tous les listings qui précèdent. On reprend, en la simplifiant la classe Action, ; double Action::calcRentabilite() int main() Action a; Ici lors de l'exécution de l'unique instruction du main, c'est le contructeur par défaut qui est appelé. On peut expliciter la déclaration implicite de la fonction constructeur : Action(); //la déclaration du constructeur par défaut. ; Action::Action() //la définition de la méthode constructeur.

double Action::calcRentabilite() int main() Action a; Ici, on a explicité la définition du constructeur. Ce constructeur était déjà défini de manière implicite. Une méthode constructeur à le nom de la classe pour laquelle elle sert à créer des objets et n'a pas de type de retour. Pour vérifier que cette fonction s'exécute bien avec l'unique instrution du main : Action(); //la déclaration du constructeur par défaut. ; Action::Action() //la définition de la méthode constructeur. std::cout << "Ceci vient du constructeur par defaut de Action\n"; double Action::calcRentabilite() int main() Action a; std::cout << coursdujour << " " << coursancien; On compile et on exécute. On constate qu'effectivement l'instruction Action a; exécute bien le code attendu. Par ailleurs, on constate que les valeurs coursdujours et coursancien sont incompréhesibles. A l'instar de ce qui se passe si on déclare une variable double sans l'initialiser, ici les variables attributs de la variables objets se voient affecter un espace mémoire dont on ne sait ce qu'il a contenu auparavant. Donc lors de la création de l'objet a, on a des valeurs incohérentes pour l'objet et donc une source d'erreur possible pour quelqu'un qui utiliserait la variable objet sans avoir initialiser convenablement

ces champs. Pour forcer à une initialisation correcte des attributs, on empêche l'utilisation du constructeur par défaut en spécifiant un constructeur. Action(double,double); //la déclaration d'un constructeur ; Action::Action(double x, double y) //la définition de la méthode constructeur. coursdujour=x; coursancien=y; double Action::calcRentabilite() int main() Action a; std::cout << a.coursdujour << " " << a.coursancien; Si on tente de compiler ce code, une erreur est renvoyée, en effet, Action a; appelle le constructeur par défaut, or celui ci n'est plus disponible puisque un constructeur a été explicitement défini. Le programmeur doit donc donner des valeurs à la création de l'objet, la documentation du code (des commentaires à rajouter à côté de la déclaration de la fonction) lui indique à quoi correspond chacun des paramètres de la fonction constructeur. Il suffit donc de remplacer le main par : Action(double,double); //la déclaration d'un constructeur ; Action::Action(double x, double y) //la définition d'une méthode constructeur.

coursdujour=x; coursancien=y; double Action::calcRentabilite() int main() Action a(12.5,13); std::cout << a.coursdujour << " " << a.coursancien; On constate qu'effectivement le code fonctionne : les attributs sont bien initialisée. La méthode constructeur récupère des valeurs pour le coursdujour et coursancien. Surcharge de constructeur A l'instar de n'importe quelle méthode de classe, il est possible de surcharger le constructeur. Notamment, il est possible de réintroduire le constructeur par défaut, si on le déclare explicitement lorsqu'un autre constructeur est déjà déclaré. Action(); Action(double,double); Action(double); ; Action::Action() coursdujour=0; coursancien=0; Action::Action(double x, double y) coursdujour=x; coursancien=y;

Action::Action(double x) coursdujour=x; coursancien=0; double Action::calcRentabilite() int main() Action a; std::cout << a.coursdujour << " " << a.coursancien << "\n"; Action a2(12,5.7); std::cout << a2.coursdujour << " " << a2.coursancien << "\n"; Action a3(12); std::cout << a3.coursdujour << " " << a3.coursancien << "\n"; Il peut y avoir plusieurs constructeur parce qu'il peut y avoir plusieurs attributs et plusieurs façon de construire un objet. Ces déclarations et les choix dépendent du contexte. Une erreur à éviter Bien noter dans le dernier listing le premier appel de constructeur dans le main. Malgré que le constructeur par défaut soit déclaré comme Action::Action();, il n'est pas possible de déclarer une variable en faisant Action a();, il faut s'en tenir à l'instruction Action a;. L'instruction Action a(); sera acceptée mais elle ne correspond pas au constructeur et provoquera rapidement des erreurs. 3 Destruction d'objets Alors qu'une méthode constructeur est appelée lors de la création d'un objet, une méthode destructeur est appelée lors de sa destruction. Pour s'en rendre compte, il suffit de rendre explicite la déclaration du constructeur par défaut : ~Action() et de lui associer une définition qui affiche un texte. A l'instar du constructeur par défaut, le destructeur par défaut est disponible sans que l'utilisateur ait besoin de la définir.

Action(); ~Action(); //on rajoute la déclaration du destructeur par défaut Action(double,double); Action(double); ; Action::Action() coursdujour=0; coursancien=0; Action::Action(double x, double y) coursdujour=x; coursancien=y; Action::Action(double x) coursdujour=x; coursancien=0; double Action::calcRentabilite() Action::~Action() //on donne une définition au destructeur par défaut std::cout << "Ceci vient du destructeur\n"; int main() Action a; std::cout << a.coursdujour << " " << a.coursancien << "\n"; Action a2(12,5.7); std::cout << a2.coursdujour << " " << a2.coursancien << "\n"; Action a3(12); std::cout << a3.coursdujour << " " << a3.coursancien << "\n"; En exécutant ce code, on se rend compte que le texte spécifié par le destructeur s'affiche 3 fois. Cela vient du fait que l'on a construit 3 objets de type Action, le destructeur est donc appelé à 3 reprises.

Il peut être intéressant de définir le destructeur par défaut. On peut penser de manière simple au fait d'un logiciel qu'on veut maintenir dans un état cohérent : chaque objet pourrait lancer une procédure de sauvegarde de son état courant lors de la destruction des objets, soit la destruction du logiciel. A noter que lorsque l'on cherche à déclarer un destructeur avec des paramètres cela n'est pas possible : le destructeur ne peut pas être surchargé. Il n'est jamais fait d'appel explicite au destructeur pour les variables locales aux fonctions qui sont définies dans la pile. On verra dans le chapitre suivant qu'on détruira les objets créés dans le tas en utilisant delete et non pas directement le destructeur. 4 Methodes const Parler d'optimisation ici mais, à ne pas forcément voir en C++ Il est possible d'utiliser le mot clé const sur une méthode. Ce mot clé indique la fonction ne contient aucune instruction de modification des membres de la classe. Ainsi dans le code qui suit, la fonction f1 #include <iostream> class A int j; void f1() const; void f2(); void f3() const; A(); ; void A::f1() const j=5; void A::f2() j=5; void A::f3() const

std::cout << "Ceci vient de f3\n"; A::A() std::cout << "Appel au constructeur\n"; int main() A vara; vara.f1(); vara.f2(); vara.f3(); return 0; Ceci provoque une erreur à la compilation à cause de la fonction f1 déclarée comme const mais qui contient une instruction de modification de j. En revanche, le code suivant se compile : #include <iostream> class A int j; void f1() const; void f2(); void f3() const; A(); ; void A::f1() const std::cout << "Ceci vient de f1\n"; void A::f2() j=5; void A::f3() const std::cout << "Ceci vient de f3\n"; A::A() std::cout << "Appel au constructeur\n";

int main() A vara; vara.f1(); vara.f2(); vara.f3(); return 0; Autant que faire se peut, il vaut mieux déclarer comme const les fonctions qui le sont, pour que le compilateur puisse détecter d'éventuelles erreurs.