Rechercher : dans
Par :

[C++] return par référence

Dernière réponse le 25 sep 2008 à 15:22:59 Omega_55, le 8 jui 2006 à 19:03:54 
 Signaler ce message aux modérateurs

Salut tout le monde,

Je programme assez bien le C++, mais je ne vois pas toujours bien ce qui se passe au niveau allocation de la mémoire.

Genre, j'ai une classe dont une méthode fait un retour par référence.

Si je fais

double& MaClasse::MaMethode()
{
double* a=new double(2);
return *a;
}

J'ai alloué de la mémoire qui ne sera pas libérée à la fin de la méthode puisque j'utilise "new".

Mais lorsque j'appelle ma méthode, je ne peux plus libérer la mémoire puisque je reçois non pas un pointeur en retour mais un objet, donc impossible de faire delete sur le "double a" retourné...

Où est l'erreur ? Faut il absolument éviter d'allouer de la mémoier avec new dans ce cas ?

Ou peut être la valeur retournée sera "locale" dans la section d'appel à la méthode, et sera détruite à la fin de cette section ?

Merci d'avance...

Configuration: Dev C++

Meilleures réponses pour « [C++] return par référence » dans :
Choisir sa carte graphique en fonction de sa référence VoirClassement des cartes graphiques par leur référence Les conseils pour le choix d'une carte graphique sont données dans l'astuce : Choisir une carte graphique pour son PC Ici, on va donner les clés de décodage pour comprendre comment les...
Les bases pour référencer votre site professionnel facilement VoirLes bases pour référencer son site professionnel facilement Avoir un site Internet c'est bien mais faire en sorte qu'il attire un grand nombre de visiteurs c'est indispensable ! En effet, le Web abrite une quantité colossale de contenus et sortir...
Référencer son site : les moteurs de recherche VoirVoici quelques autres "trucs" à savoir pour référencer un site. Les moteurs de recherche où il faut à tout prix présenter son site : 1) DMOZ ( www.dmoz.org). Ce site est très important car Google, Yahoo, Lycos, Voila... vont tous rechercher des...
Télécharger Visual C++ Express VoirVisual C++ Express est une version "gratuite" et allégée de Visual Studio ; l'utilisation requiert l'inscription sur le site de Microsoft. Cet environnement de développement permet de créer des application Win32 ou du .NET C.
Les accesseurs et les mutateurs en langage C++ VoirLa protection des données membres L'un des aspects les plus essentiels du concept « orienté objet » est l'encapsulation, qui consiste à définir des étiquettes pour les données membres et les fonctions membres afin de préciser si celles-ci sont...
Les objets en langage C++ VoirLa création d'objets En C++, il existe deux façons de créer des objets, c'est-à-dire d'instancier une classe : de façon statique de façon dynamique La création statique La création statique d'objets consiste à créer un objet en lui affectant un...

1

Char Snipeur, le 9 jui 2006 à 20:38:00

Salut.
Je vais pas t'apporter grand chose.
Mais je sais que j'ai le même problème. Normalement, le compilateur te renvoi un warning comme quoi tu retourne une référence locale.
Moi, je me satisfait du peux de fuite mémoire que cela entraine.
D'un autre coté, je ne voi pas ton intéret à retourner un double&
moi je retourne des double* afin de retourner des tableaux
En fait, pour répondre plus précisemment à ta question, tu as une fuite de mémoire.
la valeur retourné si elle n'est pas affecter est perdu, mais la mémoire n'est pas libérer Salutation !
Char Snipeur

Répondre à Char Snipeur

2

Omega_55, le 10 jui 2006 à 12:52:15

Salut Char Snipeur,

"moi je retourne des double* afin de retourner des tableaux "

Justement, puisqu'on parle de ça, j'ai aussi une difficulté là !

On m'a dit qu'il n'y avait pas de différence entre un tableau dynamique et un pointeur (ou peut être même un pointeur de pointeur, je ne sais plus)...

Mais alors, comment on fait si on veut rajouter un élément (équivalent à un push_back sur vector) ?

Si j'ai bien compris:

double* a=new double(3);

C'est un peu comme:

a[0]=3;

Mais alors si je veux rajouter un élément à mon "tableau" comme si c'était un vector<double> ?

A+

Répondre à Omega_55

3

gaby10, le 10 jui 2006 à 13:04:54

double& MaClasse::MaMethode()
{
double* a=new double(2);
return *a;
}


salut est ce que tu n'es pas en train de retourner la reference a un objet qui est decedé à la fin de ta procedure.Je pense en faisant un truc de ce genre cela resoud le probleme

double *b;
double& MaClasse::MaMethode()
{
double* a=new double(2);
b=a;
return *b;
}

Répondre à gaby10

4

Char Snipeur, le 10 jui 2006 à 16:30:42

Oui, c'est sur, tu passes par une variable globale.
mais à ce moment la, tu risque de créer des liens bizard entre varible...
en effet, tableau et pointeur, c'est pareil.
par exemple, tu peux faire :
*(a+3)
c'est équivalent à a[3].
Pour les tableau, c'est
a=new double[3];
pour un tableau à 3 cases
ensuite, tu doi pouvoir faire un
a=new double[4];
pour ajouter un élement, mais je ne suis pas sur de la copie des valeurs.
En fait, à quoi te sert ton double& ? Salutation !
Char Snipeur

Répondre à Char Snipeur

5

gaby10, le 11 jui 2006 à 11:05:38

à quoi te sert ton double& ?
pouyr dire que je retourne une reference à une variable

Répondre à gaby10

6

Char Snipeur, le 11 jui 2006 à 12:57:29

Ok, je comprend quand la variable fait partie de la class, genre
struct A{double a;...}
double& A::var(){return a;}
te permet de faire directement
A.var()=3;
mais si tu crée la variable dans la fonction, je ne voi pas l'intéret. Salutation !
Char Snipeur

Répondre à Char Snipeur

7

kilian, le 11 jui 2006 à 17:04:42

Oui, je ne comprend pas pourquoi tu veux retourner l'objet et non pas le pointeur vers l'objet.

Tu préfères peut être les points aux flêches :-) ?

Plus sérieusement, en récupérant le pointeur vers l'objet, au moins tu pourras le détruire plus tard.

Répondre à kilian

8

nico, le 25 sep 2008 à 12:39:40
  • +1

Justement, le passage par référence évite d'utiliser les pointeurs, qui appartiennent plus au monde du C.
Pourquoi les aurait-on ajouter dans le langage sinon ?

Les références permettent notamment d'utiliser des pointeurs comme des objets, en évitant la copie qui peut être longue et non voulue dans certains cas.

Si tu n'as pas de problème avec ton code initial :

double& MaClasse::MaMethode()
{
double* a=new double(2);
return *a;
}

Tu pourras toujours libérer la mémoire plus tard:

double& d = MonInstance.MaMethode ();

delete &d; // prend l'adresse de d.


Petite précision: a la sortie de la méthode, ce n'est pas le double qui est perdu, c'est le pointeur vers un double.

Répondre à nico

9

kilian, le 25 sep 2008 à 13:56:23

Deux ans plus tard je suis d'accord avec toi ;-) Alors comme ça je fais le zouave hein?

Répondre à kilian

10

nico, le 25 sep 2008 à 14:42:16

Un étudiant avait le même problème et il est tombe sur ce thread, ou la réponse n'avait pas été fournie !

Juste pour les suivants,,, ;-)

Répondre à nico

11

Char Snipeur, le 25 sep 2008 à 15:15:37

Je ne trouve ça quand même pas très propre du point de vue "bonne manière" de faire ainsi.
L'utilisateur qui utilise la fonction n'est pas forcément au courant de la manière dont est faite la fonction.
Si il récupère la variable dans une donnée "classique" (ce qui est faisable)
double a=MonInstance.MaMethode ();
alors là il y a bien un problème de mémoire que l'on ne peut rendre.
Et de toute manière un tel utilisateur ignorant si il y a un new ou pas ne sait pas si il doit libérer la mémoire.
MaMethode() peut très bien retourné une référence à une variable de MonInstance qui n'utilise alors pas de new (ou carement à une variable globale).
En revanche, si on retourne un pointeur, par convention on peut s'attendre à avoir à le libérer. Salutation !  avant je croyais, maintenant je suis fixé.Jésus Christ
Char Snipeur

Répondre à Char Snipeur

12

 nico, le 25 sep 2008 à 15:22:59

Je ne répondais pas a une manière de (bien) faire les choses, je ne répondais juste a une question d'implémentation...

On peut toujours lever le doute dont tu parles en lisant le code, si on ne la pas fait soi-même. Une documentation sérieuse précisera ce genre de problème de mémoire... etc...

Répondre à nico