2013-05-24 2 views
5

Ich bin neu in C++ - Programmierung, wenn ich einige C++ - Programme habe ich einen Zweifel, warum Kopie Konstruktor aufgerufen wird, wenn ich passiere ein Objekt als Argument nach Wert für eine Funktion. Bitte beachten Sie meinen unten stehenden Code, indem ich ein Objekt der Klasse als Argument nach Wert an eine Funktionsanzeige übergebe(), aber das Aufrufen des Kopierkonstruktors und dann der Steuerung trifft die display() -Funktion, aber ich verstehe, warum es so bitte hilft.Warum kopieren Konstruktor ist Aufruf, wenn wir ein Objekt übergeben als Argument nach Wert zu einer Methode

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

class ClassA 
{ 
    private: 
     int a, b; 
    public: 
     ClassA() 
     { 
      a = 10, b = 20; 
     } 
     ClassA(ClassA &obj) 
     { 
      cout << "copy constructor called" << endl; 
      a = obj.a; 
      b = obj.b; 
     } 
}; 
void display(ClassA obj) 
{ 
    cout << "Hello World" << endl; 
} 
int main() 
{ 
    ClassA obj; 
    display(obj); 
    return 0; 
} 

Antwort

6

die beiden Antworten schon etwas gegeben zu erarbeiten:

Wenn Sie Variablen definieren „das gleiche wie“ eine andere Variable zu sein, Sie haben grundsätzlich zwei Möglichkeiten:

ClassA aCopy = someOtherA; //copy 
ClassA& aRef = someOtherA; //reference 

Statt nicht const lvalue Referenzen gibt es natürlich const Referenzen und rvalue Referenzen. Die Hauptsache hier ist, dass aCopy unabhängig von someOtherA ist, während aRef ist praktisch die gleiche Variable wie someOtherA, es ist nur ein anderer Name (Alias) dafür.

Mit Funktionsparameter ist es im Grunde das Gleiche. Wenn der Parameter eine Referenz ist, wird er beim Aufruf der Funktion an das Argument gebunden, und es ist nur ein Alias ​​für dieses Argument. Das heißt, was Sie mit dem Parameter tun, tun Sie mit dem Argumente:

void f(int& iRef) { 
    ++iRef; 
} 

int main() { 
    int i = 5; 
    f(i); //i becomes 6, because iRef IS i 
} 

Wenn die Parameter ein Wert ist, ist es nur eine Kopie des Arguments, so unabhängig, was Sie auf die Parameter zu tun, das Argument bleibt unverändert.

void f(int iCopy) { 
    ++iCopy; 
} 

int main() { 
    int i = 5; 
    f(i); //i remains 5, because iCopy IS NOT i 
} 

Wenn Sie nach Wert übergeben, ist der Parameter ein neues Objekt. Es muss sein, denn es ist nicht dasselbe wie das Argument, es ist unabhängig. Das Erstellen eines neuen Objekts, das eine Kopie des Arguments ist, bedeutet, dass der Kopierkonstruktor oder der Move-Konstruktor aufgerufen wird, je nachdem, ob das Argument ein Lvalue oder ein Rvalue ist. In Ihrem Fall ist es unnötig, die Funktion als Wert zu übergeben, weil Sie nur das Argument lesen.

Es gibt eine Leitlinie von GotW #4:

Bevorzugen Sie einen Nur-Lese-Parameter von const & vorbei, wenn Sie von ihm zu lesen, werden (nicht eine Kopie davon machen).

4

Da durch den Wert an eine Funktion bedeutet, dass die Funktion des Objekt seine eigene Kopie hat. Zu diesem Zweck wird der Kopierkonstruktor aufgerufen.

void display(ClassA obj) 
{ 
    // display has its own ClassA object, a copy of the input 
    cout << "Hello World" << endl; 
} 

Beachten Sie, dass Kopien in einigen Fällen elided werden können, zum Beispiel, wenn ein temporärer Wert an die Funktion übergeben wird.

2

Wie Juanchopanza sagte :, übergeben Sie nach Wert, der eine Kopie erstellt wird. Wenn Sie dies verhindern möchten, können Sie durch einen Verweis:

void display(const ClassA &obj) 

Auf Nebenbei bemerkt: Sie sollten Ihre Kopie Ctor erklären das Argument als konstante Referenz zu nehmen:

ClassA(const ClassA &obj) 

Andernfalls werden Sie nicht sein Kann den copy ctor auf benannte Objekte verwenden, die als const oder mit provisories gekennzeichnet sind. Es verhindert auch, dass Sie versehentlich das übergebene Objekt ändern.

Verwandte Themen