bonjour,
je suis en train de me poser une question assez trivial :
Si je déclare une fonction qui retourne un string par exemple,
est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
quels sont les avantages et inconvénients
des deux méthodes
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Wang Zangkun
Le Fri, 28 Oct 2005 20:17:24 +0200, thierry nivon a écrit :
bonjour, je suis en train de me poser une question assez trivial : Si je déclare une fonction qui retourne un string par exemple, est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
quels sont les avantages et inconvénients des deux méthodes
amicalement, Thierry
quand tu as la fonction string toto(), il y a recopie du résultat renvoyé par toto; tu peux donc renvoyer une variable locale à la fonction toto.
avec string& toto(), tu renvoies une référence, ça ne peut donc pas être une variable locale à toto. Il n'y a pas recopie du résultat, donc tu économise un tout petit peu en temps et en mémoire, mais pour une string ça doit pas avoir beaucoup d'effet.
Maintenant, que ce soit const string&, je crois que cela veut dire que tu ne peux plus modifier le résultat de toto. Le seul avantage reste ici la non recopie de la valeur.
(avec un string& toto, tu peux faire du toto() = "a", ou appeler une méthode de la classe string sur la fonction toto, mais c'est plus très beau, ni compréhensible ni forcément intéressant).
Le Fri, 28 Oct 2005 20:17:24 +0200, thierry nivon a écrit :
bonjour,
je suis en train de me poser une question assez trivial :
Si je déclare une fonction qui retourne un string par exemple,
est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
quels sont les avantages et inconvénients
des deux méthodes
amicalement,
Thierry
quand tu as la fonction string toto(), il y a recopie du résultat
renvoyé par toto; tu peux donc renvoyer une variable locale à la
fonction toto.
avec string& toto(), tu renvoies une référence, ça ne peut donc pas
être une variable locale à toto. Il n'y a pas recopie du résultat, donc
tu économise un tout petit peu en temps et en mémoire, mais pour une
string ça doit pas avoir beaucoup d'effet.
Maintenant, que ce soit const string&, je crois que cela veut dire que tu
ne peux plus modifier le résultat de toto. Le seul avantage reste ici la
non recopie de la valeur.
(avec un string& toto, tu peux faire du toto() = "a", ou appeler une
méthode de la classe string sur la fonction toto, mais c'est plus très
beau, ni compréhensible ni forcément intéressant).
Le Fri, 28 Oct 2005 20:17:24 +0200, thierry nivon a écrit :
bonjour, je suis en train de me poser une question assez trivial : Si je déclare une fonction qui retourne un string par exemple, est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
quels sont les avantages et inconvénients des deux méthodes
amicalement, Thierry
quand tu as la fonction string toto(), il y a recopie du résultat renvoyé par toto; tu peux donc renvoyer une variable locale à la fonction toto.
avec string& toto(), tu renvoies une référence, ça ne peut donc pas être une variable locale à toto. Il n'y a pas recopie du résultat, donc tu économise un tout petit peu en temps et en mémoire, mais pour une string ça doit pas avoir beaucoup d'effet.
Maintenant, que ce soit const string&, je crois que cela veut dire que tu ne peux plus modifier le résultat de toto. Le seul avantage reste ici la non recopie de la valeur.
(avec un string& toto, tu peux faire du toto() = "a", ou appeler une méthode de la classe string sur la fonction toto, mais c'est plus très beau, ni compréhensible ni forcément intéressant).
kanze
thierry nivon wrote:
je suis en train de me poser une question assez trivial : Si je déclare une fonction qui retourne un string par exemple, est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
Ça dépend de ce que tu veux faire.
Si tu veux renvoyer une référence à une chaîne existante, il faut utiliser le deuxième forme. Ce cas arrive surtout quand la référence n'est pas const : toto est, par exemple, une fonction membre d'un objet qui contient une chaîne, et tu veux que le client puisse modifier la chaîne de l'objet. À titre d'exemple : std::vector< std::string >::operator[]( size_t ) ; On peut aussi vouloir renvoyer une référence quand il s'agit d'un type « entité », c-à-d un type où l'identité joue un rôle (et qui typiquement ne peut pas être copié).
On renvoie par valeur si ce qu'on veut renvoyer est une valeur et que le client n'a pas besoin d'en connaître la providence. Et que le client est libre à faire ce qu'il veut avec l'objet renvoyé, sans que ça influe sur l'objet d'origine.
quels sont les avantages et inconvénients des deux méthodes
Elles font des choses différentes. Si tu as une chaîne (comme membre, élément, variable globale, etc.), et tu veux donner au client accès à cette chaîne, il faut renvoyer une référence. Si tu veux renvoyer une valeur, éventuellement calculée à la volée, pour que le client en fasse ce qu'il veut, il faut renvoyer une valeur.
En général, renvoyer une référence donne un couplage fort entre toi et le client -- le client a accès à tes éléments internes. Dans certains cas, comme les collections, c'est ce qu'on veut. Mais en règle générale, si on ne sait pas d'office, c'est la valeur qui doit prévaloir.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
thierry nivon wrote:
je suis en train de me poser une question assez trivial :
Si je déclare une fonction qui retourne un string par exemple,
est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
Ça dépend de ce que tu veux faire.
Si tu veux renvoyer une référence à une chaîne existante, il
faut utiliser le deuxième forme. Ce cas arrive surtout quand la
référence n'est pas const : toto est, par exemple, une fonction
membre d'un objet qui contient une chaîne, et tu veux que le
client puisse modifier la chaîne de l'objet. À titre d'exemple :
std::vector< std::string >::operator[]( size_t ) ;
On peut aussi vouloir renvoyer une référence quand il s'agit
d'un type « entité », c-à-d un type où l'identité joue un rôle
(et qui typiquement ne peut pas être copié).
On renvoie par valeur si ce qu'on veut renvoyer est une valeur
et que le client n'a pas besoin d'en connaître la providence. Et
que le client est libre à faire ce qu'il veut avec l'objet
renvoyé, sans que ça influe sur l'objet d'origine.
quels sont les avantages et inconvénients des deux méthodes
Elles font des choses différentes. Si tu as une chaîne (comme
membre, élément, variable globale, etc.), et tu veux donner au
client accès à cette chaîne, il faut renvoyer une référence. Si
tu veux renvoyer une valeur, éventuellement calculée à la volée,
pour que le client en fasse ce qu'il veut, il faut renvoyer une
valeur.
En général, renvoyer une référence donne un couplage fort entre
toi et le client -- le client a accès à tes éléments internes.
Dans certains cas, comme les collections, c'est ce qu'on veut.
Mais en règle générale, si on ne sait pas d'office, c'est la
valeur qui doit prévaloir.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
je suis en train de me poser une question assez trivial : Si je déclare une fonction qui retourne un string par exemple, est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
Ça dépend de ce que tu veux faire.
Si tu veux renvoyer une référence à une chaîne existante, il faut utiliser le deuxième forme. Ce cas arrive surtout quand la référence n'est pas const : toto est, par exemple, une fonction membre d'un objet qui contient une chaîne, et tu veux que le client puisse modifier la chaîne de l'objet. À titre d'exemple : std::vector< std::string >::operator[]( size_t ) ; On peut aussi vouloir renvoyer une référence quand il s'agit d'un type « entité », c-à-d un type où l'identité joue un rôle (et qui typiquement ne peut pas être copié).
On renvoie par valeur si ce qu'on veut renvoyer est une valeur et que le client n'a pas besoin d'en connaître la providence. Et que le client est libre à faire ce qu'il veut avec l'objet renvoyé, sans que ça influe sur l'objet d'origine.
quels sont les avantages et inconvénients des deux méthodes
Elles font des choses différentes. Si tu as une chaîne (comme membre, élément, variable globale, etc.), et tu veux donner au client accès à cette chaîne, il faut renvoyer une référence. Si tu veux renvoyer une valeur, éventuellement calculée à la volée, pour que le client en fasse ce qu'il veut, il faut renvoyer une valeur.
En général, renvoyer une référence donne un couplage fort entre toi et le client -- le client a accès à tes éléments internes. Dans certains cas, comme les collections, c'est ce qu'on veut. Mais en règle générale, si on ne sait pas d'office, c'est la valeur qui doit prévaloir.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
kanze
Wang Zangkun wrote:
je suis en train de me poser une question assez trivial : Si je déclare une fonction qui retourne un string par exemple, est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
quels sont les avantages et inconvénients des deux méthodes
quand tu as la fonction string toto(), il y a recopie du résultat renvoyé par toto; tu peux donc renvoyer une variable locale à la fonction toto.
Ou une valeur calculée à la volée, du genre : return dirname + '/' + filename + ".cc" ;
avec string& toto(), tu renvoies une référence, ça ne peut donc pas être une variable locale à toto. Il n'y a pas recopie du résultat, donc tu économise un tout petit peu en temps et en mémoire, mais pour une string ça doit pas avoir beaucoup d'effet.
Surtout, la sémantique est différente.
Maintenant, que ce soit const string&, je crois que cela veut dire que tu ne peux plus modifier le résultat de toto. Le seul avantage reste ici la non recopie de la valeur.
(avec un string& toto, tu peux faire du toto() = "a", ou appeler une méthode de la classe string sur la fonction toto, mais c'est plus très beau, ni compréhensible ni forcément intéressant).
Ça dépend. Tu rejetterais quelque chose comme :
std::vector< std::string > v ; // ... v.at( i ) = "xyz" ;
?
Tout dépend de la sémantique.
En revanche, il faut se méfier beaucoup de l'histoire de gagner une copie avec std::string const&. Parce que bon gré mal gré, on expose des détails de l'implémentation, et on limite l'utilisation. Donc, si par la suite, je modifie le code pour que la valeur soit calculée, je suis obligé aussi de modifier l'interface, et déclencher la récompilation de tous mes clients. Et évidemment, si le client veux faire quelque chose du genre :
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Wang Zangkun wrote:
je suis en train de me poser une question assez trivial : Si
je déclare une fonction qui retourne un string par exemple,
est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
quels sont les avantages et inconvénients des deux méthodes
quand tu as la fonction string toto(), il y a recopie du
résultat renvoyé par toto; tu peux donc renvoyer une variable
locale à la fonction toto.
Ou une valeur calculée à la volée, du genre :
return dirname + '/' + filename + ".cc" ;
avec string& toto(), tu renvoies une référence, ça ne peut
donc pas être une variable locale à toto. Il n'y a pas recopie
du résultat, donc tu économise un tout petit peu en temps et
en mémoire, mais pour une string ça doit pas avoir beaucoup
d'effet.
Surtout, la sémantique est différente.
Maintenant, que ce soit const string&, je crois que cela veut
dire que tu ne peux plus modifier le résultat de toto. Le seul
avantage reste ici la non recopie de la valeur.
(avec un string& toto, tu peux faire du toto() = "a", ou
appeler une méthode de la classe string sur la fonction toto,
mais c'est plus très beau, ni compréhensible ni forcément
intéressant).
Ça dépend. Tu rejetterais quelque chose comme :
std::vector< std::string > v ;
// ...
v.at( i ) = "xyz" ;
?
Tout dépend de la sémantique.
En revanche, il faut se méfier beaucoup de l'histoire de gagner
une copie avec std::string const&. Parce que bon gré mal gré, on
expose des détails de l'implémentation, et on limite
l'utilisation. Donc, si par la suite, je modifie le code pour
que la valeur soit calculée, je suis obligé aussi de modifier
l'interface, et déclencher la récompilation de tous mes clients.
Et évidemment, si le client veux faire quelque chose du genre :
je suis en train de me poser une question assez trivial : Si je déclare une fonction qui retourne un string par exemple, est-ce qu'il est plus judicieux de déclarer
string toto()
ou bien
const string & toto()
quels sont les avantages et inconvénients des deux méthodes
quand tu as la fonction string toto(), il y a recopie du résultat renvoyé par toto; tu peux donc renvoyer une variable locale à la fonction toto.
Ou une valeur calculée à la volée, du genre : return dirname + '/' + filename + ".cc" ;
avec string& toto(), tu renvoies une référence, ça ne peut donc pas être une variable locale à toto. Il n'y a pas recopie du résultat, donc tu économise un tout petit peu en temps et en mémoire, mais pour une string ça doit pas avoir beaucoup d'effet.
Surtout, la sémantique est différente.
Maintenant, que ce soit const string&, je crois que cela veut dire que tu ne peux plus modifier le résultat de toto. Le seul avantage reste ici la non recopie de la valeur.
(avec un string& toto, tu peux faire du toto() = "a", ou appeler une méthode de la classe string sur la fonction toto, mais c'est plus très beau, ni compréhensible ni forcément intéressant).
Ça dépend. Tu rejetterais quelque chose comme :
std::vector< std::string > v ; // ... v.at( i ) = "xyz" ;
?
Tout dépend de la sémantique.
En revanche, il faut se méfier beaucoup de l'histoire de gagner une copie avec std::string const&. Parce que bon gré mal gré, on expose des détails de l'implémentation, et on limite l'utilisation. Donc, si par la suite, je modifie le code pour que la valeur soit calculée, je suis obligé aussi de modifier l'interface, et déclencher la récompilation de tous mes clients. Et évidemment, si le client veux faire quelque chose du genre :