next up previous contents index
suivant: Valeurs de retour multiples monter: main précédent: Portée   Table des matières   Index


Passage par référence

C++, comme Pascal, offre deux modes de passage des arguments à une fonction : par valeur, et par référence. Par contre, C12, Java et CAML, par simplicité n'en offrent qu'un, le passage par valeur, tandis que Fortran fait le choix inverse.

Dans un passage par référence, ce n'est pas la valeur de l'argument qui est utilisée dans le corps de la fonction, c'est l'argument lui-même, en tant qu'objet, qui est utilisé et modifié : ces modifications resteront donc visibles après le retour de la fonction. Le passage par référence s'applique à un argument si le paramètre correspondant a été déclaré en acollant & à son type. L'argument correspondant doit être une expression désignant un objet.

Par exemple, voici une procédure qui incrémente son argument entier13 :


void inc(int& x) {
  x = x+1;
}

int main() {
  int n = 4;

  inc(n);
  cout << n << endl;           // n vaut maintenant 5
  
  return 0;
}

Un autre exemple classique est la fonction qui échange la valeur de deux variables :


void swap(int& x, int& y) {
  int temp = x;

  x = y;
  y = temp;
}

int main() {
  int a=1, b=2;

  swap(a, b);
  cout << a << " " << b << endl;
  return 0;
}

Ce mécanisme est basé sur le constructeur de types références & : si $T$ est un type, $T$& est le type des références aux objets de type $T$. Celui-ci peut figurer comme type d'argument et comme type de retour des fonctions. Ce sera le mode de passage privilégié quand les arguments sont des objets volumineux. Le passage d'argument et le retour sont basées sur l'initialisation des variables de ce type. On doit initialiser une variable de type $T$& par une variable (ou plus généralement une expression qui désigne un objet) de type $T$. Il serait incorrect d'appeler inc(4) ou swap(1,2), car les arguments de ces appels sont des valeurs et ne désignent aucun objet (c'est-à-dire n'ont pas d'existence en mémoire). Il serait également incorrect d'appeler inc(n) si n est définie comme une constante :


  const int n = 4;

  inc(n);                      // ERREUR
  inc(4);                      // ERREUR

Dans les deux cas, il s'agit d'une erreur de type. La fonction inc a un paramètre de type int&. Or les règles de typage du langage interdisent que l'on initialise une variable de type $T$& par une variable de type const $T$ (car la constance serait perdue) ou par une valeur de type $T$ (car une valeur n'est pas un objet).


next up previous contents index
suivant: Valeurs de retour multiples monter: main précédent: Portée   Table des matières   Index
R Lalement