Rechercher : dans
Par :

C++ Fonctions amies

Dernière réponse le 8 déc 2007 à 17:32:21 Laaris, le 8 déc 2007 à 10:47:17 
 Signaler ce message aux modérateurs

Bonjour,

J'ai une question à propos des classes amies en C++ (j'ai déjà posté ça ailleurs mais ce n'était pas le bon forum, désolé pour le doublon)

Comment fait-on pour déclarer "amie" une fonction d'une autre classe sans déclarer "amie" la classe entière?

J'ai lu quelque part qu'il faut "préciser son nom complet à l'aide de l'opérateur de résolution de portée" mais qu'est-ce donc qu'un opérateur de résolution de portée?

Merci d'avance.

Configuration: Windows XP
Firefox 2.0.0.9

Meilleures réponses pour « C++ Fonctions amies » dans :
Trier un tableau sans utiliser la fonction sort VoirTrier un tableau sans utiliser la fonction sort D'abord on initialise une variable $max avec la 1ère valeur de tableau. Ensuite on va faire une boucle tant que le tableau contient encore des éléments. C'est avec la fonction splice qui a le rôle...
Les piles en langage C VoirLes piles Requis I. INTRODUCTION II. Définition III. La construction du prototype d'un élément de la pile IV. Opérations sur les piles A. Initialisation B. Insertion d'un élément dans la pile C. Ôter un élément de la pile D. Affichage...
Liste simplement chaînée VoirLISTES SIMPLEMENT CHAINÉES Requis I. INTRODUCTION II. Définition III. La construction du prototype d'un élément de la liste IV. Opérations sur les listes chaînées A. Initialisation B. Insertion d'un élément dans la liste 1. Insertion...
Langage C - Les fonctions VoirLa notion de fonction On appelle fonction un sous-programme qui permet d'effectuer un ensemble d'instructions par simple appel de la fonction dans le corps du programme principal. Les fonctions permettent d'exécuter dans plusieurs parties du...
Langage C++ - Les fonctions VoirLa notion de fonction On appelle fonction un sous-programme qui permet d'effectuer un ensemble d'instructions par simple appel de la fonction dans le corps du programme principal. Les fonctions permettent d'exécuter dans plusieurs parties du...

1

le père, le 8 déc 2007 à 11:37:00

Bonjour

L'opérateur de résolution de portée c'est ::

Si ta fonction amie est membre d'une classe, il faut que tu la déclares amie par
friend returntype maclasse::mafonction(parametres);

Si elle n'est pas membre d'une classe, il n'y a bien sûr pas de maclasse::

Répondre à le père

2

pascal.barbier, le 8 déc 2007 à 11:44:32

Dans l'exemple qui suit, la classe B se déclare "amie" de la fonction fct de la classe A. Ainsi, cette fonction pourra utiliser la partie privée de la classe B :

class A
{
public:
	int fct(int a, int b);
};
class B
{
friend int A::fct(int a, int b);
private:
	static void f(void) {}
};

L'opérateur de résolution de portée est le double deux-points qui précède le nom de la méthode dans la déclaration friend. Il permet de préciser à quelle classe appartient cette fonction.
Pour plus de précisions voir :
Thinking in C++ : http://bruce-eckel.developpez.com/...

Répondre à pascal.barbier

3

Laaris, le 8 déc 2007 à 12:04:36

Merci pour cette info, mais un autre problème se pose.

Si je fais:

class A
{
public:
int fct(B instance_de_B);
};
class B
{
friend int A::fct(int a, int b);
private:
static void f(void) {}
};

le compilateur me dit "B has not been declared", et si je déclare B avant A, il me dit "A has not been declared"

Répondre à Laaris

4

le père, le 8 déc 2007 à 12:17:22

Si j'en crois mon manuel C++, ce problème est classique et ne peut être contourné qu'en déclarant la classe complète comme friend :

class B
{
friend class A;
private:
static void f(void) {}
};

class A
{
public:
int fct(B instance_de_B);
};

ce qui est moins propre, puisque toutes les fonctions membres de A ont maintenant accès à la partie privée de B.

Répondre à le père

5

Laaris, le 8 déc 2007 à 12:23:58

ça risque de faire la même chose non?

Répondre à Laaris

6

pascal.barbier, le 8 déc 2007 à 12:36:04

Deux choses :
d'abord int fct(B instance_de_B); va créer une copie temporaire de instance_de_B dans la pile. Ce qui peut avoir des effets indésirables (copy constructeur). Il vaut mieux passer une référence de instance_de_B. Si on veut garantir que cet objet ne sera pas modifié par fct (comme dans le cas d'un passage par valeur) il suffit de déclarer la référence const :

int fct(const B& instance_de_B); 

Deuxième chose :
dans la classe A si on n'utilise qu'une référence de B, il suffit de faire précéder le prototype de la classe A par la déclaration d'existance de la classe B :
class B;
class A 
{ 
public: 
    int fct(const B& instance_de_B); 
}; 
class B 
{ 
    friend int A::fct(int a, int b); 
private: 
    static void f(void) {} 
}; 

Répondre à pascal.barbier

7

le père, le 8 déc 2007 à 14:27:45

Je ne crois pas que le compilateur apprécie la redéfinition de class B;. As-tu essayé ?

Répondre à le père

8

pascal.barbier, le 8 déc 2007 à 16:53:45

Bien sur c'est une technique courante qui permet d'utiliser des pointeurs ou des références d'une classe avant d'en avoir donné le prototype détaillé.

Répondre à pascal.barbier

9

le père, le 8 déc 2007 à 17:27:25

Le compilateur n'aime pas, mais pour une autre raison, tu n'as pas mis les mêmes paramètres à A::fct dans A et dans B

Le problème dont je parle n'intervient pas ici, il se pose quand il y a des friend croisés entre deux classes :

class A;
class B;

class B 
{ 
    friend int A::fct(const B& instance_de_B); 
    static void f(void) {} 
}; 

class A 
{ 
    friend void B::f(void); 
    int fct(const B& instance_de_B); 
}; 

Répondre à le père

10

 pascal.barbier, le 8 déc 2007 à 17:32:21

Pour la définition de la fonction fct mille excuses c'est un copier/coller trop rapide.

En ce qui concerne les friends croisés effectivement on ne peut pas s'en sortir sans déclarer une amitié de classe.

Toutefois le cas doit être très rare d'avoir à déclarer deux amitiés croisées de fonctions. Personnellement je n'ai quasiment jamais eu besoin des déclarations d'amitié. En général une petite revue d'architecture permet de trouver une solution plus pure.

Répondre à pascal.barbier