wake-up-neo.com

Warum sollte der Kopierkonstruktor seinen Parameter als Referenz in C ++ akzeptieren?

Warum muss einem Kopierkonstruktor sein Parameter als Referenz übergeben werden?

104
Jony

Denn wenn es nicht nach Referenz ist, ist es nach Wert. Dazu erstellen Sie eine Kopie und rufen den Kopierkonstruktor auf. Aber um das zu tun, müssen wir einen neuen Wert erstellen, also rufen wir den Kopierkonstruktor auf und so weiter ...

(Sie würden eine unendliche Rekursion haben, weil "um eine Kopie zu erstellen, müssen Sie eine Kopie erstellen".)

164
GManNickG

Weil pass-by-value den Kopierkonstruktor aufrufen würde :)

63
Brian Roach

Die Alternative zur Referenzübergabe ist die Wertübergabe. Wertübergabe ist wirklich Kopieübergabe. Der Kopierkonstruktor wird zum Erstellen einer Kopie benötigt.

Wenn Sie nur eine Kopie erstellen müssten, um den Kopierkonstruktor aufzurufen, wäre dies ein Rätsel.

(Ich denke, die unendliche Rekursion würde im Compiler auftreten und Sie würden niemals ein solches Programm bekommen.)

Abgesehen von rationalen Gründen ist dies nach der Norm in §12.8/3 verboten:

Eine Deklaration eines Konstruktors für eine Klasse X ist falsch, wenn der erste Parameter vom Typ (optional cv-qualifiziert) X ist und entweder keine anderen Parameter vorhanden sind oder alle anderen Parameter Standardargumente haben.

19
Potatoswatter

Es wäre unendlich rekursiv, wenn Sie es als Wert übergeben würden

12
Romain Hippeau

wenn Sie eine Funktion aufrufen (Beispiel: int f (car c)), deren Argumente sich von den eingebauten Datentypen unterscheiden (hier car), müssen Sie das vom Aufrufer angegebene Objekt in die Variable im Parameter der aufgerufenen Funktion kopieren.
Beispiel: car carobj; f (carobj);

das heißt, kopieren Sie carobj nach c.

carobj muss in Funktion f auf Parameter c kopiert werden.

Um das Kopieren zu erreichen, wird der Kopierkonstruktor aufgerufen.

In diesem Fall wird die Funktion f aufgerufen, indem der Wert übergeben wird, oder mit anderen Worten, die Funktion f wird als Wert übergeben deklariert.

Wenn die Funktion f als Referenz übergeben wird, lautet ihre Deklaration int f (car & c);

In diesem Fall car carobj; f (carobj); benötigt keinen Kopierkonstruktor.

In diesem Fall wird c zum Alias ​​von carobj.

Unter Verwendung der obigen 2 Szenarien fasse ich sie aus Gründen der Klarheit wie folgt zusammen: 1. Wenn eine Funktion deklariert ist, dass sie einen Parameter als Wert eines Objekts annimmt, wird der Kopierkonstruktor des Objekts aufgerufen. 2. Wenn eine Funktion deklariert, dass ein Parameter als Referenz übergeben werden soll, wird der Parameter zum Alias ​​des vom Aufrufer bereitgestellten Objekts. Kein Kopierkonstruktor erforderlich!

Nun stellt sich die Frage, warum eine Referenzübergabe erforderlich ist. Wenn der Kopierkonstruktor eine Referenz akzeptiert, wird die empfangende Variable zu einem Alias ​​des angegebenen Objekts. Daher muss der Konstruktor copy nicht (in diesem Fall muss er selbst aufgerufen werden), um den Wert im vom Aufrufer angegebenen Objekt in die Variable des Konstruktors in der Argumentliste zu kopieren.

Andernfalls, wenn der Kopierkonstruktor das vom Aufrufer bereitgestellte Objekt als Wert annimmt, d. H. Als Wert übergeben, dann benötigt er den Kopierkonstruktor des gegebenen Objekts; Um das vom Aufrufer bereitgestellte Objekt in unsere Funktion selbst zu bekommen (in diesem Fall den Kopierkonstruktor), müssen wir den Kopierkonstruktor aufrufen, der nichts anderes ist, als die gleiche Funktion während der Initialisierung der Funktionsparameter selbst aufzurufen. Dies ist der Grund für die Übergabe eines Verweises an den Kopierkonstruktor.

3
Sriraman

Es ist erforderlich, das Objekt als Referenz und nicht als Wert zu übergeben, da bei Übergabe als Wert die Kopie mit dem Kopierkonstruktor erstellt wird. Dies bedeutet, dass der Kopierkonstruktor sich selbst aufruft, um eine Kopie zu erstellen. Dieser Prozess wird fortgesetzt, bis der Compiler ausgeführt wird der Erinnerung.

0
anand tripathi

Es ist sehr wichtig, Objekte als Referenz zu übergeben. Wenn ein Objekt als Wert an den Kopierkonstruktor übergeben wird, ruft sich sein Kopierkonstruktor selbst auf, um den Aktualparameter in den Formalparameter zu kopieren. Dadurch wird eine endlose Aufrufkette an den Kopierkonstruktor eingeleitet. Dieser Vorgang wird fortgesetzt, bis dem System der Speicher ausgeht.

Daher sollte in einem Kopierkonstruktor der Parameter immer als Referenz übergeben werden.

0
Dalbir Singh

Wenn es nicht als Referenz übergeben wird, wird es als Wert übergeben. Wenn das Argument als Wert übergeben wird, ruft sein Kopierkonstruktor sich selbst auf, um den Aktualparameter in den Formalparameter zu kopieren. Dieser Vorgang würde so lange fortgesetzt, bis das System keinen Speicher mehr hat. Wir sollten es also als Referenz übergeben, damit der Kopierkonstruktor nicht aufgerufen wird.

0
ishaang