Copie
La première question à se poser
Dans le code C++, il faut faire attention au signe = en se posant la question :
Que se passe-t-il lorsqu’on écrit : A = B ?
Dans tous les cas, la variable A va contenir une information identique à la variable B. Cependant, deux scénarios peuvent se produire :
Soit la variable A est une copie indépendante de la variable B et ces deux variables vont évoluer séparément dans le programme : toute action ou modification de l’une ne se reportera pas sur l’autre.
Soit la variable A est une référence à la variable B et, dans ce cas, elle est juste un alias vers la variable B : lorsque l’on utilise le nom A, on manipule en fait la variable originale B.
Note
Il existe un troisième scénario où la variable A est une copie partielle de la variable B. Dans ce cas, certains éléments de la variable A sont des copies et d’autres des références. A notre niveau, nous éviterons cette situation car elle est source de nombreux bugs.
La réponse à cette question n’est pas immédiate car elle dépend fortement du contexte et notamment du type de A et de B. Nous allons dans la suite examiner différents scénarios en les testant par des exemples.
Comportement pour les affectations
Pour les types fondamentaux
Veuillez exécuter le code suivant dans votre environnement préféré, puis analysez les affichages.
#include <iostream>
int main()
{
// type entier
int a = 10;
int b = a;
b++;
std::cout << a << " " << b << std::endl;
// type double
double c = 5;
double d = c;
d++;
std::cout << c << " " << d << std::endl;
// type bool
double e = true;
double f = e;
f = !f;
std::cout << e << " " << f << std::endl;
}
Pour chaque type testé, indiquez si l’affirmation correspondante est vraie ou fausse :
L’affectation sur des variables de type entier produit une copie. |
L’affectation sur des variables de type double produit une copie. |
L’affectation sur des variables de type booléen produit une copie. |
Pour les structures
Examinons maintenant le type structure. Veuillez exécuter le code suivant dans votre environnement préféré, analysez ensuite les affichages.
#include <iostream>
struct v
{
int x;
int y;
};
int main()
{
// type structure
v B;
B.x = 10;
B.y = 20;
v A;
A = B; // le cas qui nous intéresse
A.x += 5;
A.y += 5;
// les affichages
std::cout <<B.x << " " << B.y << std::endl;
std::cout <<A.x << " " << A.y << std::endl;
}
Indiquez si l’affirmation suivante est vraie ou fausse :
L’affectation sur des variables de type structure produit une copie. |
Passage de paramètres
Cas des types fondamentaux
Le passage d’un argument à une fonction peut soit déclencher une copie soit mettre en place une référence. Nous allons donc vérifier ce qu’il se passe en exécutant le code suivant et en analysant les résultats.
#include <iostream>
void F(int a, double b, bool c)
{
std::cout << "Entrée de fonction : " << a << " " << b << " " << c << std::endl;
a += 1;
b += 1;
c = !c;
std::cout << "Sortie de fonction : " << a << " " << b << " " << c << std::endl;
}
int main()
{
// type entier
int a = 10;
double b = 20.0;
bool c = true;
std::cout << "Avant l'appel : " << a << " " << b << " " << c << std::endl;
F(a,b,c);
std::cout << "Après l'appel : " << a << " " << b << " " << c << std::endl;
}
Pour chaque type testé, indiquez si l’affirmation correspondante est vraie ou fausse :
Le passage de paramètres avec un type entier produit une copie. |
Le passage de paramètres avec un type double produit une copie. |
Le passage de paramètres avec un type booléen produit une copie. |
Cas des structures
Le langage a-t-il voulu rester dans la logique des comportements précédents ou a-t-il choisi une autre stratégie ? Veuillez exécuter le code suivant, puis analysez les résultats.
#include <iostream>
struct v
{
int x;
int y;
};
void F(v a)
{
std::cout << "Entrée de fonction : " << a.x << " " << a.y << std::endl;
a.x += 1;
a.y += 2;
std::cout << "Sortie de fonction : " << a.x << " " << a.y << std::endl;
}
int main()
{
// type structure
v a;
a.x = 10;
a.y = 20;
std::cout << "Avant l'appel : " << a.x << " " << a.y << std::endl;
F(a);
std::cout << "Après l'appel : " << a.x << " " << a.y << std::endl;
}
Indiquez si l’affirmation suivante est vraie ou fausse :
Le passage de paramètres avec un type structure produit une copie des informations contenues dans la structure. |
Conclusion
Suite à nos tests, nous constatons que le C++ a choisi d’avoir un comportement homogène pour l’affectation et le passage d’arguments et ceci pour l’ensemble des types testés. En résumé, nous pouvons conclure par :
REGLE : En C++, l’affectation et le passage d’arguments se font toujours par copie aussi pour les types fondamentaux que pour les structures.