Académique Documents
Professionnel Documents
Culture Documents
- la suppression de l’objet :
2
2-Cas d’une classe avec constructeur
L’opérateur new appellera un constructeur de l’objet.
new puisse appeler un constructeur disposant d’arguments
Syntaxe:
new point (1, 2) ;
s’il n’existe pas de constructeur, ou s’il existe un constructeur sans argument.
Acceptées
5
Emploi du constructeur de recopie par défaut: lorsque aucun
constructeur de recopie n’a été défini.
Exemple: l’utilisation de la classe vecteur et de transmettre par valeur un
objet de type vect à une fonction nommée fct:
#include <iostream>
using namespace std ;
class vecteur
{ int n_element ; // nombre d’éléments
double * adr ; // pointeur sur ces éléments
public : void fct (vecteur b)
vecteur (int n) // constructeur "usuel" { cout << "*** appel de fct ***\n" ;
{ adr = new double [n_element = n] ; }
cout << "+ const. usuel - adr objet : " << this main()
<< " - adr vecteur : " << adr << "\n" ; { vecteur a(2) ;
} fct (a) ;
~vecteur () }
{ cout << "- Destr. objet - adr objet : "
<< this << " - adr vecteur : " << adr << "\n" ;
delete adr ;
}
}; 6
CONSTRUCTEUR DE COPIE
On peut éviter ce problème en faisant en sorte que l’appel : fct (a) ;
conduise à créer « intégralement » un nouvel objet de type vect, avec ses
membres données (nelem et adr), mais aussi son propre emplacement de
stockage
Solution: Le constructeur de copie permet d’initialiser un objet en copiant les
attributs d’un autre objet du même type.
Syntaxe :
NomClasse(NomClasse & autre) { ... }
Exemple :
: hauteur(autre.hauteur), largeur(autre.largeur)
{}
7
Le constructeur par copie est appelé: passée par valeur à une fonction
#include <iostream>
using namespace std ;
class vecteur
{ int nelem ; // nombre d’éléments
double * adr ; // pointeur sur ces éléments
public :
vecteur (int n) // constructeur "usuel"
{ adr = new double [nelem = n] ;
cout << "+ const. usuel - adr objet : " << this<< " - adr vecteur : " << adr << "\n" ;}
vecteur (const vecteur & v) // constructeur de copie
{ adr = new double [nelem = v.nelem] ; // création nouvel objet
int i ; for (i=0 ; i<nelem ; i++) adr[i]=v.adr[i] ; // recopie de l’ancien
cout << "+ const. recopie - adr objet : " << this<< " - adr vecteur : " << adr << "\n" ;
}
~vect () // destructeur
{ cout << "- Destr. objet - adr objet :" << this << " - adr vecteur : " << adr << "\n" ;
delete adr ;
}
};
void fct (vecteur b)
{ cout << "*** appel de fct ***\n" ; }
main()
{ vecteur a(2) ; fct (a) ;// Le constructeur par copie est appelé: passée par valeur à une8
fonction
}
LE CONSTRUCTEUR DE COPIE
+ const. usuel - adr objet : 0X6AFDE4 - adr vecteur : 0X7D0320
+ const. recopie - adr objet : 0X6AFD88 - adr vecteur : 0X7D0100
*** appel de fct ***
- Destr. objet - adr objet : 0X6AFD88 - adr vecteur : 0X7D0100
- Destr. objet - adr objet : 0X6AFDE4 - adr vecteur : 0X7D0320
r1 et r2 sont deux objets distincts mais ayant des mêmes valeurs pour leurs
attributs
9
#include <iostream>
using namespace std ;
class point
{ int x, y ;
public :
point (int abs=0, int ord=0) // constructeur "usuel"
{ x=abs ; y=ord ;
cout << "++ Appel Const. usuel " << this << " " << x << " " << y << "\n" ;
}
point (const point & p):x(p.x), y(p.y) // constructeur de recopie
//{ x=p.x ; y=p.y ;
{cout << "++ Appel Const. recopie " << this << " " << x << " " << y << "\n" ;
}
~point ()
{ cout << "-- Appel Destr. " << this << " " << x << " " << y << "\n" ;
}
point symetrique () ;
};
point point::symetrique ()
{ point res ; res.x = -x ; res.y = -y ; return res ;
}
main()
{ point a(1,3), b ;
cout << "** avant appel de symetrique\n" ;
b = a.symetrique () ;
point c(b);//
point c=b;//
10
cout << "** apres appel de symetrique\n" ;
}
Mise en œuvre des constructeurs et des destructeurs: Appel des
différents constructeurs dans le cas d’objets membres
Exemple: Soient les deux classes point et cercle
class point
{ int x, y ;
public :
point (int, int) ;
};
class cercle
{ point centre ;
int rayon ;
public :
cercle (int, int, int) ;
};
cercle::cercle (int abs, int ord, int ray) : centre (abs, ord)// l’en-tête de cercle spécifie,
après les deux-points, la liste des arguments qui seront transmis à point.
{ ...
}
11
#include <iostream>
using namespace std ;
class point
{ int x, y ;
public :
point (int abs=0, int ord=0)
{ x=abs ; y=ord ;
cout << "Constr. point " << x << " " << y << "\n" ;
}
};
class cercle
{ point centre ;
int rayon ;
public :
cercle (int , int , int) ;
};
cercle::cercle (int abs, int ord, int ray) : centre(abs, ord)
{ rayon = ray ;
cout << "Constr. cercle " << rayon << "\n" ;
}
main()
{cercle a (1,3,5) ;}
Constructeur: cercle::cercle (int abs, int ord, int ray)
{ rayon = ray ;
centre = point (abs, ord) ; 12
cout << "Constr. cercle " << rayon << "\n" ;
}
Les tableaux d’objets
En C++, un tableau peut posséder des éléments de n’importe quel type, y compris de
type objet: ce qui conduit alors à des tableaux d’objets
point courbe [10]//
for (i = 0 ; i < 10 ; i++) courbe[i].affiche() ;// Exemple:
using namespace std ;
class point
{ int x, y ;
public :
point (int abs=0, int ord=0)
{ x=abs ; y =ord ;
cout << "++ Constr. point : " << x << " " << y << "\n" ;
}
~point ()
{ cout << "-- Destr. point : " << x << " " << y << "\n" ;
}
};
main()
{ int n = 2 ;
point courbe[4] = {5, n, 2*n } ;
cout << "*** fin programme ***\n" ;
}
13
Cas des tableaux dynamiques d’objets
Pour créer dynamiquement un tableau de points en faisant appel à l’opérateur new:
Exemple :
point * courbe = new point[10] ;
Pour détruire notre tableau d’objets:
delete [] courbe
Les objets temporaires
Soit le constructeur :point (int, int) ;
Soit affectation telle que : a = point (1, 2) ;
point (1, 2)// la création d’un objet temporaire de type point
Rq: Quant à l’objet temporaire ainsi créé, il n’a plus d’intérêt dès que l’instruction
d’affectation est exécutée. La norme prévoit qu’il soit détruit dès que possible (qui se
trouve détruit tout de suite après).
main()
{ point a(0,0) ; //
a = point (1, 3) ; // 14
a = point (3, 4) ; //
cout << " Fin main \n" ;}
DÉVELOPPEMENT EN C++:
PROGRAMMATION ORIENTÉE OBJET
AVEC C++
15
AU 2019-2020
LES FONCTIONS AMIES
Le principe d'encapsulation fait qu'une classe interdit à ses
utilisateurs externes l'accès à ses membres privés
17
SOLUTION
Le C++ dispose d'un outil qui permet de contourner l'encapsulation dans
certaines circonstances et pour certaines fonctions.
18
LA NOTION D'AMITIÉ
• L'amitié peut être entre une fonction et une classe ou même entre deux
classes.
o Une fonction amie d'une classe est autorisée à accéder aux membres
privés comme n'importe quel autre membre de cette classe.
20
FONCTION AMIE D'UNE CLASSE
Exemple :
21
EXEMPLE
//fonction indépendante, amie d'une int main()
classe {point a(4,0),b(4,0),c(1,3);
#include <iostream.h> if(coincide(a,b))cout<<"a coincide
using namespace std; avec b\n";
class point else cout<<"a est different de b\n";
{ if(coincide(a,c))cout<<"a coincide
private: avec c\n";
int x,y; else cout<<"a est different de c\n";
public: system("pause");
point(int abs=0,int ord=0){x=abs;y=ord;} return 0 ;}
//declaration de la fonction amie
friend int coincide(point,point);
};
int coincide(point p,point q)
{if((p.x==q.x)&&(p.y==q.y)) 22
return 1;
else return 0;}
FONCTION MEMBRE AMIE D'UNE CLASSE
La fonction amie d'une classe peut ne pas être indépendante mais
plutôt une fonction membre d'une autre classe.
class A
{
………
friend TypeRetour B::F(Liste des paramètres);
………
}; 23
FONCTION AMIE DE PLUSIEURS CLASSES
-Une fonction peut avoir besoin d'accéder aux membres privés de plusieurs classes et
nécessite par conséquent d'être déclarée amie de toutes ces classes en même temps.
-La déclaration d'amitié doit se faire dans ce cas dans toutes ces classes.
Exemple : On considère une fonction indépendante F qui doit accéder aux membres
privés de deux classes A et B. Le prototype de F est le suivant : void F(A, B); F doit
être déclarée amie à la fois à A et B : class B;
class A// Définition de A
{………
friend void F(A, B);
………
};
Syntaxe : class B // Définition de B
{………
friend void F(A, B);
………
};
void F(A a, B b) 24
{
… … …}
CLASSE AMIE D'UNE AUTRE CLASSE
Ce cas de figure est une généralisation de l'amitié d'une fonction membre à
une classe.
Il s'agit de déclarer toutes les fonctions d'une classe A comme amies aux
fonctions membres d'une autre classe B.
Mais, le C++ offre une alternative qui consiste à effectuer une déclaration
d'amitié globale entre les classes. Ainsi, il suffit de déclarer la classe A comme
étant amie de la classe B.
class A
{
… … …};
Syntaxe : class B
{
………
friend class A;
… … …}; 25
Dans ce cas, toutes les méthodes de A seront ainsi amies de B.