2013-05-24 10 views
5

sono nuovo alla programmazione in C++, quando sto facendo alcuni programmi in C++ ho un dubbio che è il motivo per cui il costruttore di copie viene chiamato quando passo un oggetto come argomento per valore di una funzione. per favore vedi il mio codice qui sotto nel senso che sto passando un oggetto di classe come argomento per valore a una funzione display() ma chiama costruttore di copia e poi controllo sta colpendo la funzione display() ma sto capendo perché è così, per favore, aiutare.perché il costruttore di copia è chiamato quando passiamo un oggetto come argomento per valore a un metodo

#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; 
} 

risposta

6

Elaborare le due risposte già dato un po ':

Quando si definiscono le variabili di essere "lo stesso di" qualche altra variabile, avete fondamentalmente due possibilità:

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

Invece di non- riferimenti di const-lvalue ci sono naturalmente riferimenti const e riferimenti rvalue. La cosa principale che voglio sottolineare qui è che aCopy è indipendente da someOtherA, mentre aRef è praticamente la stessa variabile di someOtherA, è solo un altro nome (alias) per esso.

Con i parametri di funzione, è praticamente lo stesso. Quando il parametro è un riferimento, viene associato all'argomento quando viene chiamata la funzione, ed è solo un alias per quell'argomento. Ciò significa che quello che fai con il parametro, si fa con l'argomento:

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

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

Quando il parametro è un valore, è solo una copia della tesi, quindi indipendentemente da quello che fai per il parametro, l'argomento Rimane invariato.

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

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

Quando si passa il valore, il parametro è un nuovo oggetto. Deve essere, poiché non è la stessa cosa dell'argomento, è indipendente. Creare un nuovo oggetto che sia una copia dell'argomento, significa chiamare il costruttore di copie o spostare il costruttore, a seconda che l'argomento sia un lvalue o un valore. Nel tuo caso, rendere superflua la funzione non è necessario, perché si legge solo l'argomento.

V'è una linea guida da GotW #4:

Preferisco il superamento di un parametro di sola lettura da const & se si sta solo andando a leggere da esso (non fare una copia di esso).

4

Poiché passare il valore di una funzione significa che la funzione ha la propria copia dell'oggetto. A tal fine, viene chiamato il costruttore di copie.

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

Tenete a mente che in alcuni casi le copie possono essere eliso, per esempio, se un valore temporaneo viene passato alla funzione.

2

Come diceva juanchopanza: si passa al valore, il che fa sì che una copia venga eseguita. Se si vuole evitare che ciò si può passare per riferimento:

void display(const ClassA &obj) 

Su un sidenote: Si dovrebbe dichiarare la ctor copia di prendere l'argomento come riferimento const:

ClassA(const ClassA &obj) 

In caso contrario non sarà in grado di utilizzare il copy ctor su oggetti denominati contrassegnati come const o con temporaries. Inoltre, impedisce di modificare accidentalmente l'oggetto passato.

Problemi correlati