Une question simple pour laquelle je n'ai pas trouvé de réponse ici.
Ce que je comprends, c’est que lorsqu’on passe un argument à une fonction pendant l’appel, par ex.
void myFunction(type myVariable)
{
}
void main()
{
myFunction(myVariable);
}
Pour les types de données simples comme int
, float
, etc., la fonction est appelée par valeur.
Mais si myVariable
est un tableau, seule l'adresse de départ est transmise (même si notre fonction est une fonction d'appel par valeur).
Si myVariable
est un objet, seule l'adresse de cet objet est transmise au lieu de créer une copie et de la transmettre.
Donc revenons à la question. C++ transmet-t-il un objet par référence ou par valeur?
Les arguments sont passés par valeur, sauf indication contraire de la signature de la fonction:
void foo(type arg)
, arg
est passé par valeur, que type
soit un type simple, un type de pointeur ou un type de classe,void foo(type& arg)
, arg
est passé par référence.Dans le cas de tableaux, la valeur transmise est un pointeur sur les premiers éléments du tableau. Si vous connaissez la taille du tableau au moment de la compilation, vous pouvez également passer un tableau par référence: void foo(type (&arg)[10])
.
C++ vous donne toujours le choix: Tous les types T
(à l'exception des tableaux, voir ci-dessous) peuvent être passés par valeur en rendant le type de paramètre T
, et passé par référence en faisant le type de paramètre T &
, reference-to -T
.
Lorsque le type de paramètre n'est pas explicitement annoté comme référence (type &myVariable
), Il est toujours transmis par valeur, quel que soit le type spécifique. Pour les types définis par l'utilisateur également (c'est à cela que sert le constructeur de copie). Également pour les pointeurs, même si la copie d'un pointeur ne copie pas ce qui est pointé.
Les tableaux sont un peu plus compliqués. Les tableaux ne peuvent pas être passés par valeur, paramètre Les types tels que int arr[]
Ne sont en réalité qu'une syntaxe différente pour int *arr
. Ce n'est pas l'acte de passer à une fonction qui produit un pointeur à partir d'un tableau, pratiquement toutes les opérations possibles (à l'exception de quelques-unes seulement comme sizeof
) le fait . Un peut passer une référence à un tableau, mais ceci explicitement annoté comme référence: int (&myArray)[100]
(notez l'esperluette).
C++ permet de passer de paradigmes passe par valeur et passe par référence.
Vous pouvez trouver deux exemples d'utilisation ci-dessous.
http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Les tableaux sont des constructions spéciales. Lorsque vous transmettez un tableau en tant que paramètre, un pointeur sur l'adresse du premier élément est transmis en tant que valeur avec le type d'élément dans le tableau.
Lorsque vous transmettez un pointeur en tant que paramètre, vous implémentez vous-même le paradigme passe par référence, comme en C. Parce que lorsque vous modifiez l'objet dans l'adresse spécifiée, vous modifiez exactement l'objet dans la fonction appelant.
En C++, les types déclarés en tant que classe, structure ou union sont considérés "de type classe". Celles-ci sont passées par valeur ou vous pouvez dire qu'une copie utilisant le constructeur de copie est passée aux fonctions. Ceci est assez évident lorsque nous implémentons des arbres binaires dans lesquels vous avez presque toujours un type de paramètre Node *) dans la fonction récursive agissant sur l'arbre binaire. Cela facilite la modification de ce noeud. Si le nœud devait être passé tel quel (c’est-à-dire qu’il ne s’agissait pas de type pointeur), les modifications apportées aux nœuds auraient été apportées à la copie locale. pour éviter que nous utilisions une référence &.