Vous êtes sur la page 1sur 7

Chapitre 4 : Les classes en C++ A.U.

: 2009/2010
ENSI – II2

Rappels

Les Classes en C++  Une classe est une implémentation d’un type abstrait de
données,
 Une classe est la généralisation de la notion de type
défini par l’utilisateur, dans lequel se trouvent associées
des données «Données membres» (ou attributs) et des
Déclaration et définition d’une classe fonctions «Fonctions membres» (ou méthodes).
Constructeur et Destructeur  En POO pure, les données sont « encapsulées »
Surcharge des opérateurs
=> leur accès ne peut se faire que par le biais des
Données statiques
Généricité
méthodes.
 C++ est un langage orienté objets :
http://msdn.microsoft.com/fr-fr/visualc/msdn.coach++.concepts.aspx

Les classes en C++ 2

Déclaration et définition d’une Exemple :


classe
 Une syntaxe possible pour la définition d’une classe est : class ABCD {
Déclaration de la classe ABCD
class <nom de classe> int i,j;
{ private :
public :
// déclaration des attributs
...
int f() { return i;}
public : };
// ...
Prototype et définition des méthodes
void main() instantiation de la classe ABCD
... en un objet a
{
};
ABCD a;
 La classe est définie à l’aide d’un bloc et se termine par un ‘;’

int i = a.f(); on applique la méthode f


} à l'objet a

Les classes en C++ 3 Les classes en C++ 4

Spécifications de protection, ou Surcharge des méthodes


de visibilité
class A { void main() class A { void main()
public : { public : {
int f() { return i;} A a; int f() { return i;} A a;
private : void f(int val ) { i=val;}
int i; int i = a.f(); private : a.f(10);
int i;
}; a.i = 5; }; printf("%d \n",a.f());

} }

illégal Affiche 10

Les classes en C++ 5 Les classes en C++ 6

1
Chapitre 4 : Les classes en C++ A.U. : 2009/2010
ENSI – II2

Modifieurs et Accesseurs Définition des méthodes

La clause optionnelle const, située après la signature désigne une class A {


méthode de type accesseur (c.a.d. ne change pas l'état de l'instance) public :
class A { ... int f() const;
public : int f() const void f(int val) { i=val;} Méthode inline par défaut
int f() { private :
{ i = 0; int i;
i = 0; return i; };
return i; }
Spécification de contexte ::
} ... int A::f() const
void f(int val) { i=val;} {
private : return i;
int i; }
};

Les classes en C++ 7 Les classes en C++ 8

Exemple Exercice n°1 : Pile d’entiers


tableau de taille 10

char c; dernier = dernier +1 dernier = dernier -1


TAB[dernier] = x; N+1
class X // X:: ::c TAB[dernier] = x;
dernier
{
x
public:
char c; X::c
class Y // X::Y::
dernier x
{
public:
-1
void f(char e) { X t; ::c = t.X::c = c = e; } void main {
private: Pile P;
class Pile {
char c; P.creer();
X::Y::c ..... P.empiler(3);
};
}; P.empiler(5); P.depiler()
};
// afficher le sommet

Les classes en C++ Les classes en C++


};
9 10

Les opérateurs de création et de


Le pointeur "this" destruction des objets
class A { class A {
public : public : char * text;
int f(); int f(); text = new char[80];
void f(int); ... ...
private : int f() }; delete text;
int i; {
}; return this->i = i; A * a;
} = (A*) malloc( sizeof(A));
this peut être interprété comme un identifiant a = new A;
de l'objet. Il fait toujours référence à l'instance int i = a->f();
pour laquelle la méthode est invoqué.
... = free a;
15
delete a;
this …
….
Les classes en C++ 11 Les classes en C++ 12

2
Chapitre 4 : Les classes en C++ A.U. : 2009/2010
ENSI – II2

Le constructeur et le
destructeur Constructeur & destructeur
L'initialisation des attributs a été faite par le modifieur void f(int);
class A { Un constructeur de A
Risque d'oubli !! public :
A(); Un constructeur surdéfini de A
A(int);
 Constructeur ...
Le destructeur
• Une fonction membre portant le même nom que sa classe se nomme
~A();
un constructeur, void main()
• Un constructeur peut avoir des arguments mais ne renvoie pas de ...
{
valeur (aucune indication de type même pas void ). };
• Le constructeur est appelé implicitement tout juste après l’allocation A a;
Le constructeur de A est exécuté par A()
de l’espace mémoire destiné à l’objet, A * ptr;
 Destructeur printf("%d \n",a.f());
Le constructeur de A est exécuté par A(int)
• Une fonction membre portant le même nom que sa classe, précédé du ...
symbole (~), se nomme destructeur,
ptr = new A(1);
• Un destructeur ne peut pas comporter d’arguments et il ne renvoie
... Le destructeur de A est exécuté
pas de valeur ( aucune indication de type ne doit être prévue ).
• Le destructeur est appelé implicitement avant la libération de l’espace delete ptr;
mémoire associé à l’objet, } Le destructeur de A est exécuté

Les classes en C++ 13 Les classes en C++ 14

Constructeur (…) Constructeur par défaut


 Le corps du constructeur peut être précédé par une section optionnelle  Lorsqu'on ne définit aucun constructeur pour une classe, le
introduite par ":", spécifiquement réservée à l'initialisation des attributs. compilateur se charge de générer automatiquement un constructeur
 Il est possible de changer la valeur des attributs dans le corps du par défaut (minimaliste = initialisation par défaut des attributs)
constructeur
 Les attributs non initialisés dans cette section prendront une valeur par class C {
défaut dans le cas où une telle valeur existe class A {
….
int i;
A objA;
public :
B objB;
A::A(int val) initialisation A() : i(10) { } auto-généré
};
: i(val) }; C() :
class B {
{ objA(),
i = ...;
int j;
public :
? objB()
affectation { }
} B(int x) : j(x) { }
};
Remarque : on utilise pas "this" si le nom de l'attribut est identique au nom de l'argument
Les classes en C++ 15 Les classes en C++ 16

Exercice n°2 : Exercice n°3 :


 CompteurCyclique : CC  Classe Personne (0 ou 1 conjoint)
 Horloge : • Nom, setConjoint(), getConjoint()
• 1ercas : CC (statique)
• 2ème cas : CC (dynamique)

Les classes en C++ 17 Les classes en C++ 18

3
Chapitre 4 : Les classes en C++ A.U. : 2009/2010
ENSI – II2

Clonage des objets Le mot clé C++ ‘explicit’


Constructeur de copie
Déclaration d’un constructeur ayant un La conversion implicite est parfois source
Forme générale unique paramètre et l’utiliser pour faire la d’erreur. Usage du mot clé explicit:
conversion.

<id_classe> (const <id_classe> & obj) : ... class A { class A {


{ public: public:
A(int); explicit A(int);
} a1 10
a2 10
}; };
void f(A) {} void f(A) {}
A::A(const A & a) void g() { void g() {
: i(a.i) A a1 = 37; A a1 = 37; // illegal
void main() A a2 = A(47); A a2 = A(47); // OK
{ A a3(57); A a3(57); // OK
i = ...; { a1 = 67; a1 = 67; // illegal
A a1; f(77); f(77); // illegal
} } }
A a2(a1);
}
A a1
a1 = 37;
37;
Creation d’un objet A avec une valeur A a1 = 37 // illégale
Remarque : s'il n'est pas défini, le compilateur génère un de manière automatique
entière. Le constructeur est appelé
( initialisation membre à membre en invoquant le constructeur de copie de chacun d'eux) "converting constructor".
Les classes en C++ 19

Surcharge des opérateurs Surcharge des opérateurs


op  <type> operator op (<type> membre_droit)
class Complex {
Op = (+, /, *, new, [], (), ++, --, =, +=, ....)
...
class Complex { Complex operator++(int) /* postfixé */
void Complex::operator ++()
float re,im;
{ };
public : Complex operator++(int)
re++;
Complex(int re,int im) {
im++; void main() return Complex(re++, im++);
: re(re) , im(im)
} { }
{ }
Complex z1(0,0);
void operator ++(); void main()
Complex z2(3,4);
}; {
z1 = z2++;
Complex z;
} z1 = 3 + 4i ; z2 = 4 + 5i
z.operator ++(); ++z;
}

Les classes en C++ 21 Les classes en C++ 22

Notions de méthode amie :


Surcharge des opérateurs friend
class Complex { Complex & operator+(const Complex & z) {  Fonction extérieure à la classe ayant accès aux
... return Complex(re+z.re, im+z.im);
// + de 2 complexes } données privées de la classes
Complex & operator*(const int & alpha) {
// * complex et entier
}; return Complex(re*alpha, im*alpha);
 Contraire à la P.O.O. mais utile dans certain cas
}  Plusieurs situations d’« amitié » :
void main() • Une fonction indépendante, amie d’une classe
{ • Une méthode d’une classe, amie d’une autre classe
Complex z1(2,3); • Une fonction amie de plusieurs classes
Complex z2(3,4);
Fonction ordinaire • Toutes les méthodes d’une classe amies d’une autre classe
z1 = z1 + z2; Complex & operator*(const int & alpha, const Complex & z)
z1 = z1 * 3; { friend type_retour NomFonction (arguments) ;
z1 = 2 * z2; return Complex( z * alpha); // A déclarer dans la classe amie
} }

Les classes en C++ 23

4
Chapitre 4 : Les classes en C++ A.U. : 2009/2010
ENSI – II2

Copy constructeur vs. Opérateur


d’affectation
Bibliothèque de flots
MaClasse c;
MaClasse c1=c; // ⇔ c1(c) En C, la librairie de fonctions En C++, une bibliothèque qui gère
// Appel au copy constructeur! d’entrées/sorties (printf, puts, des flots de données
MaClasse c2; fopen, fwrite, fclose,
c2=c1; // Appel de l’opérateur d’affectation! sprintf, …)

// Si la méthode Egal a été définie par :


// bool Egal(MaClasse c); #include <iostream>
if(c1.Egal(c2)) …; // Appel du copy constructeur! #include <cstdio> using std;
// c2 est recopié dans c
void main() void main()
// Si l’opérateur == a été surchargé par : { {
// bool operator==(MaClasse c); puts(" Bonjour "); cout << " Bonjour ";
if(c1==c2) …; // Appel du copy constructeur! } }
// c1.operator==(c2)
// c2 est recopié dans c

Les classes en C++ 26

cout (…)
formatage

printf("%d %s %lu \n", 10, " Salut ", 15567L);


cout << 10 << " Salut " << 15567L << endl;

cadrage
1
printf(" %5d", 1);
cout.width(5); cout << 1;
précision
3 . 1 4 1
printf(" %.3f", 3.1415927);
cout.precision(3); cout << 3.1415927;

Les classes en C++ ioStreamManip


27 28

cout & cerr & cin (…) Fichiers & Tampon (…)
Fichiers : ifstream / ofstream
cout : sortie standard ostream entrée / sortie
cerr : sortie des erreurs
#include <fstream>
cerr << " erreur " << endl;
ifstream fileIn("nom_fichier_physique");
fileIn >> x;

Tampon (buffer):
istream entrée / sortie istrstream, ostrstream
cin : entrée standard
#include <strstream>
int age; char * p = new char[20];
char name[20]; ostrstream ch(p, 20);
cin >> age >> name; ch << "age=" << 14;

Les classes en C++ 29 Les classes en C++ 30

5
Chapitre 4 : Les classes en C++ A.U. : 2009/2010
ENSI – II2

Connexion d’un flot à un fichier Connexion d’un flot à un fichier


 Librairie à inclure : #include <fstream>  Méthode héritée de la classe istream par ifstream et fstream :
• Classe ifstream : Interface pour les fichier en lecture (input) • istream& read (char* s, streamsize n ); // Lire
• Classe ofstream : Interface pour les fichier en écriture (output) • streampos tellg ( ); // Retourner la position du curseur
• Classe fstream : Interface pour manipuler les fichiers (Lecture/Écriture)
• istream& seekg (streampos pos) // Déplacer le curseur
 Ouverture d’un fichier : par le constructeur de la classe ou par la // Déplacement du curseur de off octets à partir dir
méthode open des classes ifstream , ofstream et fstream
• istream& seekg (streamoff off, ios_base::seekdir dir);
void open (const char * filename, openmode mode = in | out); • – ios_base::beg : Depuis le début
En cas d’erreur : bool bad()const; retourne true
• – ios_base::cur : Depuis la position courante
Mode d’ouverture : possibilité de cumuler les modes avec | • – ios_base::end : depuis la fin
• ios_base::app : Ouverture en ajout (à la fin) - mode append
• Lecture d’une chaîne jusqu’à un délimiteur (‘/n’ par défaut) – insertion de ‘/0’
• ios_base::ate : Ouverture et position du curseur à la fin du fichier
• – istream& getline/get (char* s, streamsize n );
• ios_base::binary : Ouverture d’un fichier en binaire (plutôt qu’en texte)
• ios_base::in : Ouverture en lecture • – istream& getline/get (char* s, streamsize n, char delim );
• ios_base::out : Ouverture en écriture  Méthode héritée de la classe ostream par ofstream et fstream :
• ios_base::trunc : Ouverture du fichier et écrasement du contenu à l’écriture
• ostream& write (const char* str , streamsize n); // Écrire
 Fermeture d’un fichier : la méthode des classes ifstream, ofstream et • streampos tellp ( );
fstream
• ostream& seekp (streampos pos); // Déplacer le curseur
void close (); • ostream& seekp (streamoff off, ios_base::seekdir dir);

31 32

Exemple
#include <iostream>
#include <fstream>
using namespace std;
int main ()
cout …
{ int length;
char * buffer; class Horloge
// Création et ouverture de deux fichiers via les constructeurs {
ifstream infile ("test.txt",ifstream::binary); public:
ofstream outfile ("new.txt",ofstream::binary); …
// Calcul de la taille du fichier
};
infile.seekg (0, ios::end); // Position à la fin
// Récupération de la position de la fin de fichier
length = infile.tellg(); ostream &operator << (ostream &out, Horloge H)
infile.seekg (0, ios::beg); // Position du curseur au début {
// Allocation mémoire pour stocker le contenu du fichier return (out << C.valH() << ":" << C.valM() << ":" << C.valS() );
buffer = new char [length]; }
// Lecture du contenu d’un fichier en un seul bloc void main()
infile.read (buffer,length); {
outfile.write (buffer, length); // Écriture dans le fichier
Horloge h(23,59,57);
delete[] buffer;
infile.close(); outfile.close(); // Fermeture des fichiers cout << h << endl;
return 0; }
}
33 Les classes en C++ 34

Exemple
// Redéfinition de l’opérateur << en fonction amie Exemple (suite)
// de la classe Point
ostream & operator << (ostream & sortie, point & p) {
sortie << "<" << p.x << "," << p.y << ">" ; return sortie ; }
void main()
// Redéfinition de l’opérateur << en fonction amie {
// de la classe Point point b
istream & operator >> (istream & entree, point & p) { cout << "donnez un point : " ;
char c = '\0' ;
int x, y ; bool ok = true ; if (cin >> b)
entree >> c ; // saisie d’un caractère au clavier cout << "Affichage du point : " << b << endl ;
if (c != '<') ok = false ; else
else { entree >> x >> c ; // saisie de x (entier)
// et d’un autre caractère au clavier
cout << "** information incorrecte" << endl ;
if (c != ',') ok = false ; }
else { entree >> y >> c ; // même chose pour y
if (c != '>') ok = false ; }
}
// Si la saisie a été correcte, on affecte à p
if (ok==true) { p.x = x ; p.y = y ; }
// Statut d’erreur du flot géré par un ensemble de bits d’un entier
// clear (activation de bits d’erreur)
// badbit (bit activé quand flot dans un état irrécupérable)
// rdstate () pur activer le bit badbit sans activer les autres
else entree.clear (ios::badbit | entree.rdstate () ) ;
// on retourne le flot d’entrée
return entree ;
} userStreamRedefOperator 36

6
Chapitre 4 : Les classes en C++ A.U. : 2009/2010
ENSI – II2

Membre donnée statique Généricité


template <class T>
class Vecteur {
 Un membre donnée déclaré avec l’attribut static est T * v;
template <class T>
partagé par tous les objets de la même classe, Vecteur<T>::Vecteur(int n) {
int taille;
v = new T[n];
 Il existe même lorsque aucun objet de cette classe n’a public :
été déclaré, taille = n;
Vecteur(int);
}
 Un membre donné statique doit être initialisé ~Vecteur();
explicitement, à l’extérieur de la classe ( même s’il est template <class T>
T & operator [] (int i); Vecteur<T>::~Vecteur() {
privé ), en utilisant l’opérateur de portée (::) pour spécifié
};
sa classe, delete []T;
class A { }
static int a;
template <class T> T &
public:
A
A Vecteur<T>::operator [] (int i){

}; return v[i];
a : int = 10
.. }
int A::a = 10;
Les classes en C++ 37 Les classes en C++ 39

Contraintes d’utilisation des


patrons : Exercice n°3
 Définition de patrons (de fonctions ou de  Pile générique de taille quelconque
classes) utilisée par le compilateur pour
instancier (fabriquer) chaque fois que
nécessaire les instructions requises
 Impossibilité de livrer à un utilisateur un début

patron de fonction ou de classe compilé P x new(P)


P.suiv = début; P.val=X;
 En pratique, placement des définitions et début = P

des implémentations de patrons (de


fonctions ou de classes) dans un fichier
approprié d'extension .h
40 Les classes en C++ 41

La classe string de C++ std::string


#include <string> // Pour utiliser les chaînes de caractères
#include <iostream>
using namespace std ;
 C++ a une bibliothèque <string> #include <string>
• Namespace : std void main()
• Constructeur : string(), string(char*), string(string) {
string MaChaine="Bonjour les camarades";
• Operator : +, +=, =, ==, !=, <, <=, >, >=, [] cout << "La Chaine de caractères \"" <<
• substr, replace, find, swap, getline(cin, s1), … MaChaine << "\" a pour taille " <<
MaChaine.size() << "." << endl;

 Plus pratique que la bibliothèque string de C (<cstring>) string AutreChaine("!!");


cout << "Concaténation des deux chaines : \""
<< MaChaine + AutreChaine<<"\"" << endl ;

42 43

Vous aimerez peut-être aussi