web-dev-qa-db-fra.com

Pourquoi le constructeur de copie devrait-il accepter son paramètre par référence en C ++?

Pourquoi un constructeur de copie doit-il passer son paramètre par référence?

104
Jony

Parce que si ce n'est pas par référence, c'est par valeur. Pour ce faire, vous effectuez une copie et pour ce faire, vous appelez le constructeur de copie. Mais pour ce faire, nous devons créer une nouvelle valeur, nous appelons donc le constructeur de copie, etc.

(Vous auriez une récursion infinie car "pour faire une copie, vous devez faire une copie".)

164
GManNickG

Parce que pass-by-value invoquerait le constructeur de copie :)

63
Brian Roach

L'alternative au passage par référence est le passage par valeur. Pass-by-value est vraiment passe-par-copie. Le constructeur de copie est nécessaire pour faire une copie.

Si vous deviez faire une copie juste pour appeler le constructeur de la copie, ce serait une énigme.

(Je pense que la récursion infinie se produirait dans le compilateur et vous n'obtiendrez jamais réellement un tel programme.)

Outre les raisons rationnelles, il est interdit par la norme du §12.8/3:

Une déclaration d'un constructeur pour une classe X est mal formée si son premier paramètre est de type (éventuellement qualifié cv) X et soit il n'y a pas d'autres paramètres, soit tous les autres paramètres ont des arguments par défaut.

19
Potatoswatter

Ce serait infiniment récursif si vous le transmettiez par valeur

12
Romain Hippeau

chaque fois que vous appelez une fonction (exemple: int f (car c)) qui prend ses arguments autres que les types de données intégrés (ici car) une exigence pour copier l'objet réel fourni par l'appelant dans la variable dans le paramètre de la fonction appelée.
exemple: car carjj; f (carobj);

c'est-à-dire, copiez carobj vers c.

carobj doit être copié au paramètre c dans la fonction f.

Pour réaliser la copie, le constructeur de copie est appelé.

Dans ce cas, la fonction f appelée en utilisant pass by value ou en d'autres termes, la fonction f est déclarée prendre pass by value.

Si la fonction f passe par référence, alors sa déclaration est int f (car & c);

Dans ce cas, carobj de voiture; f (carobj); n'a pas besoin d'un constructeur de copie.

Dans ce cas, c devient alias de carobj.

En utilisant les 2 scénarios ci-dessus, pour votre clarté, je les résume comme suit: 1. Si une fonction déclarée pour prendre un paramètre comme valeur d'un objet, alors le constructeur de copie de l'objet est appelé. 2. Si une fonction a déclaré prendre un paramètre comme référence par passage, le paramètre devient l'alias de l'objet fourni par l'appelant. Pas besoin de constructeur de copie!

Maintenant, la question est de savoir pourquoi passer par référence est requis. Si le constructeur de copie accepte la référence, la variable de réception devient des alias de l'objet fourni. Par conséquent, pas besoin de copier le constructeur (dans ce cas, appeler à lui-même) pour copier la valeur dans l'objet fourni par l'appelant pour copier la variable du constructeur dans la liste d'arguments.

Sinon, si le constructeur de copie prend l'objet fourni par l'appelant comme valeur, c'est-à-dire passer par valeur, alors il a besoin du constructeur de copie de l'objet donné; Par conséquent, pour obtenir l'objet fourni par l'appelant dans notre fonction elle-même (dans ce cas, le constructeur de copie), nous devons appeler le constructeur de copie, qui n'est rien d'autre que d'appeler la même fonction pendant l'initialisation des paramètres de fonction elle-même. C'est la raison de passer une référence au constructeur de copie.

3
Sriraman

Il est nécessaire de passer l'objet comme référence et non par valeur car si vous le transmettez par valeur, sa copie est construite à l'aide du constructeur de copie. de mémoire.

0
anand tripathi

Il est très essentiel de passer des objets comme référence. Si un objet est transmis en tant que valeur au constructeur de copie, son constructeur de copie s'appellera lui-même pour copier le paramètre réel dans le paramètre formel. Ainsi, une chaîne d'appel sans fin vers le constructeur de copie sera lancée. Ce processus se poursuivrait jusqu'à ce que le système manque de mémoire.

Par conséquent, dans un constructeur de copie, le paramètre doit toujours être transmis comme référence.

0
Dalbir Singh

Si ce n'est pas passé par référence, il passerait par valeur. Si l'argument est passé par valeur, son constructeur de copie s'appellera pour copier le paramètre réel dans le paramètre formel. Ce processus se poursuivrait jusqu'à ce que le système manque de mémoire. Donc, nous devons le passer par référence, afin que le constructeur de copie ne soit pas invoqué.

0
ishaang