2010-04-28 7 views
8

Je sais que si vous écrivez void nom_fonction (int & a), alors la fonction ne fera pas de copie locale de votre variable passée en argument. Aussi rencontré dans la littérature que vous devez écrire void nom_fonction (const int & a) pour dire compilateur, que je ne veux pas que la variable passée en argument soit copiée.Différence d'argument de fonction comme (const int &) et (int & a) en C++

Donc ma question: quelle est la différence avec ces deux cas (sauf que "const" assure que la variable passée ne sera pas changée par fonction !!!) ???

+0

est-il pas la différence entre 'const int &' int et a' ou même 'a' const int le point réel a'? Je me demande pourquoi le compilateur devrait faire une différence entre 'const int & a' et' const int a'? Ou est-ce que l'utilisation et la garantie que le compilateur ne fera pas de copie et que 'const int a' le force à faire une copie? Comment pouvez-vous dire «laisser le compilateur choisir»? – kriss

+0

Voir aussi ici: http://stackoverflow.com/questions/2139224/2139254#2139254 – sbi

+1

@kriss: Le compilateur ne peut pas choisir. Considérons que vous déclarez une fonction 'void f ( int x);'. Au moment de la déclaration, le compilateur n'a aucune information indiquant si vous voulez ou non modifier l'objet. En voyant seulement le code, il peut affirmer que le code ne change pas ou change le paramètre. Et même alors, si le code change un paramètre, comment le compilateur peut-il savoir si vous voulez que ce changement soit visible en dehors de la fonction? Même s'il pouvait décider avec la définition, comment le compilateur considérerait-il la signature dans les unités de traduction où seul l'en-tête est inclus? –

Répondre

10

Vous devez utiliser const dans la signature chaque fois que vous n'avez pas besoin d'écrire. L'ajout de const à la signature a deux effets: il indique au compilateur que vous voulez qu'il vérifie et garantisse que vous ne modifiez pas cet argument dans votre fonction. Le deuxième effet est que le code externe peut utiliser votre fonction en passant des objets qui sont eux-mêmes constants (et temporaires), permettant plus d'utilisations de la même fonction.

En même temps, le mot-clé const est une partie importante de la documentation de votre fonction/méthode: la signature de la fonction indique explicitement ce que vous avez l'intention de faire avec l'argument, et s'il est sûr de passer un objet fait partie des invariants d'un autre objet dans votre fonction: vous êtes explicite en ce sens que vous ne jouez pas avec leur objet. L'utilisation de const force un ensemble d'exigences plus strict dans votre code (la fonction): vous ne pouvez pas modifier l'objet, mais en même temps il est moins restrictif dans vos appelants, ce qui rend votre code plus réutilisable.

void printr(int & i) { std::cout << i << std::endl; } 
void printcr(const int & i) { std::cout << i << std::endl; } 
int main() { 
    int x = 10; 
    const int y = 15; 
    printr(x); 
    //printr(y); // passing y as non-const reference discards qualifiers 
    //printr(5); // cannot bind a non-const reference to a temporary 
    printcr(x); printcr(y); printcr(5); // all valid 
} 
7

So my question: what is the difference with this two cases (except that "const" enshures that the variable passes will not be changed by function!!!)???

Ce est la différence.

+0

Je me suis de l'aspect de la copie. – Narek

+0

@Narek: le paramètre 'const' n'affecte pas si une copie est effectuée ou non. Passer par référence ('const' ou non) évitera une copie. Passer par valeur (sans utiliser de référence) provoquera une copie, que le paramètre soit 'const' ou non.L'utilisation d'un paramètre de référence 'const' pour un' int' est généralement considérée comme inutile, puisque le passage par valeur n'a pas de coût supplémentaire dans ce cas. –

+0

@Michael: et qu'en est-il de 'const int' vs' int'? – kriss

1

Vous indiquez la différence à droite. Vous pouvez également formuler comme:

Si vous souhaitez spécifier que la fonction peut changement l'argument (par exemple pour init_to_big_number(int& i) en spécifiant l'argument par référence (variable) En cas de doute, spécifiez-le const

..

Notez que l'avantage de ne pas copier l'argument est dans les performances, c'est-à-dire pour les objets "chers" .Pour les types intégrés comme int cela n'a aucun sens d'écrire void f(const int& i). Passer la référence à la variable est tout aussi coûteux que de passer la valeur

0

Ils sont utilisés à des fins différentes es. Le passage d'une variable à l'aide de const int& garantit que vous obtiendrez la sémantique de passage par copie avec de meilleures performances. Vous êtes assuré que la fonction appelée (sauf si elle fait des choses folles en utilisant const_cast) ne modifiera pas votre argument passé sans créer de copie. int& est utilisé lorsqu'il existe généralement plusieurs valeurs de retour d'une fonction. Dans ce cas, ceux-ci peuvent être utilisés pour conserver les résultats de la fonction.

+2

Mais vous ne passez pas par la sémantique de copie avec 'const int &'. Les modifications externes de l'objet transmis seront visibles dans la fonction appelée. Ce n'est certainement pas un passage par la sémantique de la copie, c'est une caractéristique du passage par référence. –

1

Il y a une grande différence en termes de paramètres qu'ils pourraient opérer, Supposons que vous avez un constructeur de copie pour votre classe de int,

customeclass(const int & count){ 
    //this constructor is able to create a class from 5, 
    //I mean from RValue as well as from LValue 
} 
customeclass(int & count){ 
    //this constructor is not able to create a class from 5, 
    //I mean only from LValue 
} 

La version const peut essentiellement fonctionner sur des valeurs temporaires et non constante La version ne pouvait pas fonctionner sur temporaire, vous seriez facilement confronté à un problème lorsque vous manquez const où il est nécessaire et utiliser STL, mais vous obtenez erreur cachée disant qu'il n'a pas pu trouver la version qui prend temporairement. Je recommande d'utiliser const où vous pouvez.

0

Je dirais que

void cfunction_name(const X& a); 

me permet de passer une référence à l'objet temporaire comme suit

X make_X(); 

function_name(make_X()); 

Alors que

void function_name(X& a); 

ne parvient pas à atteindre cet objectif. avec l'erreur suivante erreur: initialisation non valide de référence non-const de type 'X &' à partir d'un temporaire de type 'X'

0

en laissant de côté la discussion sur les performances, laissez parler le code!

void foo(){ 
    const int i1 = 0; 
    int i2 = 0; 
    i1 = 123; //i gets red -> expression must be a modifiyble value 
    i2 = 123; 
} 
//the following two functions are OK 
void foo(int i) { 
    i = 123; 
} 
void foo(int & i) { 
    i = 123; 
} 
//in the following two functions i gets red 
//already your IDE (VS) knows that i should not be changed 
//and it forces you not to assign a value to i 
//more over you can change the constness of one variable, in different functions 
//in the function where i is defined it could be a variable 
//in another function it could be constant 
void foo(const int i) { 
    i = 123; 
} 
void foo(const int & i) { 
    i = 123; 
} 

en utilisant « const » où il est nécessaire présente les avantages suivants: * vous pouvez modifier la constness d'une variable i, dans différentes fonctions dans la fonction où i est définie, il pourrait être une variable une autre fonction pourrait être une valeur constante. * déjà votre IDE sait que je ne devrais pas être changé. et il vous oblige à ne pas attribuer une valeur à i

ce qui a trait Oops

Questions connexes