Vous êtes sur la page 1sur 17

Chapitre 4 : Fonctions amies

Master SEIB
Azzedine DLIOU
École Nationale des Sciences Appliquées
Université Ibn Zohr

2020-2021
Sommaire

1 Introduction
2 Fonction indépendante amie d’une classe
3 Fonction membre d’une classe amie d’une autre classe
4 Fonction amie de plusieurs classes
5 Toutes les fonctions d’une classe amies d’une autre classe
6 Exemples
Introduction

La notion de fonction amie propose une solution intéressante, sous


la forme d’un compromis entre encapsulation formelle des données
privées et des données publiques.
Lors de la définition d’une classe, il est possible de déclarer qu’une ou
plusieurs fonctions (extérieures à la classe) sont des « amies ».
Une telle déclaration d’amitié les autorise à accéder aux données pri-
vées, au même titre que n’importe quelle fonction membre.
Il existe plusieurs situations d’amitiés :
1 Fonction indépendante, amie d’une classe ;
2 Fonction membre d’une classe, amie d’une autre classe ;
3 Fonction amie de plusieurs classes ;
4 Toutes les fonctions membres d’une classe, amies d’une autre classe.
Fonction indépendante amie d’une classe
Présentation

Soit la fonction coincide examinant la « coïncidence » de deux objets


de type point.
Si nous voulons faire de la fonction coincide une fonction indépen-
dante amie de la classe point, il faut, tout d’abord, introduire dans
la classe point la déclaration d’amitié appropriée à savoir :
friend bool coincide (const point &, const point &) ;
Il s’agit précisément du prototype de la fonction coincide, précédé du
mot clé friend.
Fonction indépendante amie d’une classe
Application

Exemple
#include <iostream>
using namespace std ;
class point{
int x, y ;
public :
point (int abs=0, int ord=0){ x=abs ; y=ord ; }
friend bool coincide (const point &, const point &) ;
} ;
bool coincide (const point &p, const point &q){
return ((p.x == q.x) && (p.y == q.y)) ;
}
int main(){
point a(1,0), b(1), c ;
if (coincide (a,b)) cout << "a coincide avec b \n" ;
else cout << "a et b sont differents \n" ;
if (coincide (a,c)) cout << "a coincide avec c \n" ;
else cout << "a et c sont differents \n" ;
}
Fonction indépendante amie d’une classe
Application

Résultat
a coincide avec b
a et c sont differents

Remarques
1 L’emplacement de la déclaration d’amitié au sein de la classe point
est absolument indifférent.
2 Nous n’avons plus d’argument implicite (this) dans notre cas ici.
3 Les deux arguments de coincide sont transmis par valeur. Ils pour-
raient l’être par référence ;
(NB : Dans le cas d’une fonction membre, l’objet appelant la fonction
est d’office transmis par référence (sous la forme de this)).
Fonction membre d’une classe amie d’une autre classe

Il s’agit un peu d’un cas particulier de la situation précédente.


Il suffit simplement de préciser, dans la déclaration d’amitié, la classe
à laquelle appartient la fonction concernée, à l’aide de l’opérateur de
résolution de portée ( : :).
Soit deux classes nommées A et B, la classe B pocède une fonction
membre f, de prototype :
int f(char, A) ;
Si f doit pouvoir accéder aux membres privés de A, elle sera déclarée
amie au sein de la classe par :
friend int B : :f(char, A) ;
Fonction membre d’une classe amie d’une autre classe
Exemple
class A
{
// partie privée
.....
// partie publique
friend int B::f (char, A) ;
.....
} ;
class B
{
.....
int f (char, A) ;
.....
} ;
int B::f (char ..., A ...)
{
// on a accès ici aux membres privés
// de tout objet de type A
}
Fonction membre d’une classe amie d’une autre classe

Remarques
1- Pour compiler convenablement les déclarations d’une classe A conte-
nant une déclaration d’amitié telle que :
friend int B : :f(char, A) ;
le compilateur a besoin de connaître les caractéristiques de B ; cela
signifie que la déclaration de B devra avoir été compilée avant celle
de A.
2- En revanche, pour compiler convenablement la déclaration :
int f(char, A)
figurant au sein de la classe B, le compilateur n’a pas besoin de
connaître précisément les caractéristiques de A. Il lui suffit de savoir
qu’il s’agit d’une classe.
On peut fournir l’information voulue au compilateur en faisant précé-
der la déclaration de B de :
class A ;
Fonction membre d’une classe amie d’une autre classe

Remarques suite
3- La compilation de la définition de la fonction f nécessite, en général,
la connaissance des caractéristiques des classes A et B ; leurs décla-
rations devront donc apparaître avant.
Par exemple :
class A ;
class B{
.....
int f(char, A) ;
.....
} ;
class A{
.....
friend int B::f(char, A) ;
.....
} ;
int B::f(char..., A...){ ..... }
Fonction amie de plusieurs classes
Une fonction (indépendante ou membre) peut faire l’objet de décla-
rations d’amitié dans différentes classes. Par exemple :

Classe A Classe B
class A{ class B{
// partie privée // partie privée
..... .....
// partie publique // partie publique
friend void f(A, B) ; friend void f(A, B) ;
..... .....
}; };

Fonction f
void f(A..., B...)
{
// on a accès ici aux membres privés
// de n’importe quel objet de type A ou B
}
Fonction amie de plusieurs classes

Remarques
1 La déclaration de A peut être compilée sans celle de B, en la faisant
précéder de la déclaration :
class B ;
2 De même, la déclaration de B peut être compilée sans celle de A, en
la faisant précéder de la déclaration :
class A ;
3 Si l’on compile en même temps les deux déclarations de A et B, il
faudra utiliser l’une des deux déclarations citées (class A si B figure
avant A, class B sinon).
4 La compilation de la définition de f nécessitera généralement les dé-
clarations de A et de B.
Toutes les fonctions d’une classe amies d’une autre classe

Une généralisation du deuxième cas.


On pourrait d’ailleurs effectuer autant de déclarations d’amitié qu’il
y a de fonctions concernées. Mais il est plus simple d’effectuer une
déclaration globale.
Pour dire que toutes les fonctions membres de la classe B sont amies
de la classe class A, on placera, dans la classe class A, la déclaration :
friend class B ;

Remarques
1 Pour compiler la déclaration de la classe A, il suffira de la faire précéder
de :
class B ;
2 Ce type de déclaration d’amitié évite de fournir les en-têtes des fonc-
tions concernées.
Exemples
Fonction amie indépendante

Classes vect et matrice Fonction prod


#include <iostream> vect prod (const matrice &m,const vect &x){
using namespace std ; int i, j ; double som ; vect res ;
class matrice ; for (i=0 ; i<3 ; i++){
class vect { for(j=0, som=0 ; j<3 ; j++)
double v[3] ; som += m.mat[i][j] * x.v[j] ;
public : res.v[i] = som ;
vect (double v1=0, double v2=0, double v3=0){ }
v[0] = v1 ; v[1]=v2 ; v[2]=v3 ; return res ;
}
friend vect prod (const matrice&, const vect &) ; }
void affiche () const{
int i ;
for (i=0 ; i<3 ; i++) cout « v[i] « " " ; Programme d’essai
cout « "\n" ;
} int main(){
vect prod(const matrice &m,const vect &x) ;
}; vect w(1,2,3) ; vect res ;
class matrice{ double tb[3][3]={{1,2,3},{4,5,6},{7,8,9}} ;
double mat[3][3] ; matrice a=tb ;
public : res = prod(a,w) ; res.affiche () ;
matrice (double t[3][3]){
int i, j ; }
for (i=0 ; i<3 ; i++)
for (j=0 ; j<3 ; j++) mat[i][j]=t[i][j] ;
}
friend vect prod(const matrice &, const vect &) ;
};
Exemples
Fonction amie indépendante

Classes vect et matrice Fonction prod


#include <iostream> vect prod (const matrice &m,const vect &x){
using namespace std ; int i, j ; double som ; vect res ;
class matrice ; for (i=0 ; i<3 ; i++){
class vect { for(j=0, som=0 ; j<3 ; j++)
double v[3] ; som += m.mat[i][j] * x.v[j] ;
public : res.v[i] = som ;
vect (double v1=0, double v2=0, double v3=0){ }
v[0] = v1 ; v[1]=v2 ; v[2]=v3 ; return res ;
}
friend vect prod (const matrice&, const vect &) ; }
void affiche () const{
int i ;
for (i=0 ; i<3 ; i++) cout « v[i] « " " ; Programme d’essai
cout « "\n" ;
} int main(){
vect prod(const matrice &m,const vect &x) ;
}; vect w(1,2,3) ; vect res ;
class matrice{ double tb[3][3]={{1,2,3},{4,5,6},{7,8,9}} ;
double mat[3][3] ; matrice a=tb ;
public : res = prod(a,w) ; res.affiche () ;
matrice (double t[3][3]){
int i, j ; }
for (i=0 ; i<3 ; i++)
for (j=0 ; j<3 ; j++) mat[i][j]=t[i][j] ;
} Résultat
friend vect prod(const matrice &, const vect &) ;
};
14 32 50
Exemples
Fonction amie membre d’une classe

Classes vect et matrice Fonction membre prod


#include <iostream> vect matrice : :prod (const vect &x){
using namespace std ; int i, j ; double som ; vect res ;
class vect ; for (i=0 ; i<3 ; i++){
class matrice{ for(j=0, som=0 ; j<3 ; j++)
double mat[3][3] ; som += m.mat[i][j] * x.v[j] ;
public : res.v[i] = som ;
matrice (double t[3][3]){ }
int i, j ; return res ;
for (i=0 ; i<3 ; i++)
for (j=0 ; j<3 ; j++) mat[i][j]=t[i][j] ; }
}
vect prod(const vect &) ;
}; Programme d’essai
class vect {
double v[3] ; int main(){
public : vect w(1,2,3) ; vect res ;
vect (double v1=0, double v2=0, double v3=0){ double tb[3][3]={{1,2,3},{4,5,6},{7,8,9}} ;
v[0] = v1 ; v[1]=v2 ; v[2]=v3 ; matrice a=tb ;
} res = prod(a,w) ;
friend vect matrice : :prod (const vect &) const ; res.affiche () ;
void affiche () const{ }
int i ;
for (i=0 ; i<3 ; i++) cout « v[i] « " " ;
cout « "\n" ;
}
};
Exemples
Fonction amie membre d’une classe

Classes vect et matrice Fonction membre prod


#include <iostream> vect matrice : :prod (const vect &x){
using namespace std ; int i, j ; double som ; vect res ;
class vect ; for (i=0 ; i<3 ; i++){
class matrice{ for(j=0, som=0 ; j<3 ; j++)
double mat[3][3] ; som += m.mat[i][j] * x.v[j] ;
public : res.v[i] = som ;
matrice (double t[3][3]){ }
int i, j ; return res ;
for (i=0 ; i<3 ; i++)
for (j=0 ; j<3 ; j++) mat[i][j]=t[i][j] ; }
}
vect prod(const vect &) ;
}; Programme d’essai
class vect {
double v[3] ; int main(){
public : vect w(1,2,3) ; vect res ;
vect (double v1=0, double v2=0, double v3=0){ double tb[3][3]={{1,2,3},{4,5,6},{7,8,9}} ;
v[0] = v1 ; v[1]=v2 ; v[2]=v3 ; matrice a=tb ;
} res = prod(a,w) ;
friend vect matrice : :prod (const vect &) const ; res.affiche () ;
void affiche () const{ }
int i ;
for (i=0 ; i<3 ; i++) cout « v[i] « " " ;
cout « "\n" ;
} Résultat
}; 14 32 50

Vous aimerez peut-être aussi