2010-02-24 13 views
1

Je suis en train d'apprendre C++, et en provenance de c, certains appels de fonctions que je vois dans le livre me confondez:fonctions C++ prennent des valeurs, où ils devraient prendre des références

char a; 
cin.get(a); 

En C, cette ne pourrait pas fonctionner, si vous faisiez cela, il n'y aurait aucun moyen d'obtenir la sortie, parce que vous passez par la valeur, et non par référence, pourquoi cela fonctionne en C++? Le référencement et le dereferncing sont-ils rendus implicites (le compilateur sait que cin.get a besoin d'un pointeur, donc il est référencé)?

+1

C Aucune référence, seulement les valeurs. C++ a des références réelles, des alias vers une autre instance. – GManNickG

+0

Alors, quel est le nom de l'opérateur unaire &? Je pensais que c'était l'opérateur de référencement. –

+2

& en C signifie "adresse de". En C++, & signifie "adresse de" (si utilisé devant une variable) ou "référence à" (si utilisé après le type dans un paramètre). – LeopardSkinPillBoxHat

Répondre

11

C++

Cela fonctionne en C++ parce que la signature de la fonction pour get() est probablement ceci:

void get(char& a); // pass-by-reference 

Le symbole & après char indique au compilateur que lorsque vous transmettez une valeur char, il doit transmettre une référence au char plutôt que de faire une copie de celui-ci. Cela signifie essentiellement que toute modification apportée au sein de get() sera reflétée dans la valeur a en dehors de la méthode.

Si la signature de fonction pour get() était le suivant:

void get(char a); // pass-by-value 

alors a serait passé par valeur, ce qui signifie une copie de a est faite avant d'être passé dans la méthode en tant que paramètre. Toute modification à a serait alors seulement la méthode locale, et perdue quand la méthode retourne.

C

La raison pour laquelle cela ne fonctionne pas en C est parce que C n'a que passe par valeur. La seule façon d'émuler passer-par-référence comportement en C est de passer son pointeur par valeur, puis de dé-référencer la valeur du pointeur (accédant ainsi au même emplacement mémoire) lors de la modification de la valeur:

void get(char* a) 
{ 
    *a = 'g'; 
} 

int main(int argc, char* argv[]) 
{ 
    char a = 'f'; 
    get(&a); 
    printf("%c\n", a); 

    return 0; 
} 

L'exécution de ce programme va afficher:

g 
4

Les types de référence fonctionnent comme cela (passez par référence, au lieu de passer par la valeur). C'est comme passer un pointeur (passer par un pointeur) en C, mais avec une syntaxe plus agréable et plus de sécurité (vérifications à la compilation). L'implémentation passe par pointeur en interne.

+1

+1. En C il * fonctionnera avec cin.get (& a) comme dans scanf ("% c", & a) qui est passé par un pointeur. –

+1

Il n'est pas nécessaire que les références soient implémentées en tant que pointeurs si je ne me trompe pas, bien qu'elles le soient généralement. – Eric

+0

Non requis, mais AFAIK toutes les implémentations le font comme ça (pour les appels de fonction, de toute façon). – Tronic

1

C++ permet passer par référence (notez le &, ce qui signifie qu'une référence est utilisée):

void foo(char& bar) { 
    bar = 42; 
} 

int main() { 
    char a; 
    foo(a); 
    // a == 42 here 
} 
1

C'est pourquoi certains programmeurs C++ n'aiment pas utiliser des références comme ça.
Cela ressemble à une fonction argument - vous n'avez aucune idée de la syntaxe si 'a' est modifié ou non.Préférez passer des références const (lorsque vous avez un objet volumineux et une copie coûterait cher) et renvoyer des références ou le meilleur de tous les pointeurs de passage.

+0

-1 car le retour par paramètre est parfaitement valide et de bon style (et les programmeurs expérimentés en C++, y compris le comité de normalisation, le font). – Tronic

+0

@Martin - cela ne fonctionne pas très bien lorsqu'une méthode doit renvoyer plusieurs valeurs. – LeopardSkinPillBoxHat

+1

Les références de retour peuvent poser des problèmes, car l'appelant ne peut pas contrôler la durée de vie de l'objet référencé par la référence renvoyée. En particulier, si vous renvoyez une référence à un objet pile, votre appelant sera dans beaucoup de chagrin :) –