Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the copy constructor called when we pass an object as an argument by value to a method?

Why is the copy constructor called when I pass an object as an argument by value to a function? Please see my below code: I am passing an object of a class as an argument by value to a function display(), but it is calling the copy constructor before control is hitting the display() function. I don't understand why.

#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;
}
like image 966
nagaradderKantesh Avatar asked May 24 '13 05:05

nagaradderKantesh


People also ask

Why copy constructor is called when we pass an object as an argument?

Because passing by value to a function means the function has its own copy of the object. To this end, the copy constructor is called.

Why is copy constructor called?

A copy constructor is called when a new object is created from an existing object, as a copy of the existing object. The assignment operator is called when an already initialized object is assigned a new value from another existing object.

Why is a class's copy constructor called when an object of that class is passed by value into a function?

Why is a class's copy constructor called when an object of that class is passed by value into a function? Because the parameter variable is created in memory when the function executes, and is initialized with the argument object. This causes the copy constructor to be called.

Why we Cannot pass the argument by value to a copy constructor?

A copy constructor cannot receive value by call by value method. While we invoke copy constructor an object of same class must be passed to it. But the object passed need to be copied in formal arguments. Values of one object is copied in another by copy constructor.


2 Answers

To elaborate the two answers already given a bit:

When you define variables to be "the same as" some other variable, you have basically two possibilities:

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

Instead of non-const lvalue references, there are of course const references and rvalue references. The main thing I want to point out here is, that aCopy is independent of someOtherA, while aRef is practically the same variable as someOtherA, it's just another name (alias) for it.

With function parameters, it's basically the same. When the parameter is a reference, it gets bound to the argument when the function is called, and it's just an alias for that argument. That means, what you do with the parameter, you do with the argument:

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

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

When the parameter is a value, it is only a copy of the argument, so regardless of what you do to the parameter, the argument remains unchanged.

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

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

When you pass by value, the parameter is a new object. It has to be, since it's not the same as the argument, it's independent. Creating a new object that is a copy of the argument, means calling the copy constructor or move constructor, depending on whether the argument is an lvalue or rvalue. In your case, making the function pass by value is unnecessary, because you only read the argument.

There is a Guideline from GotW #4:

Prefer passing a read-only parameter by const& if you are only going to read from it (not make a copy of it).

like image 124
Arne Mertz Avatar answered Oct 07 '22 01:10

Arne Mertz


Because passing by value to a function means the function has its own copy of the object. To this end, the copy constructor is called.

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

Bear in mind that in some cases copies may be elided, for instance, if a temporary value is passed to the function.

like image 25
juanchopanza Avatar answered Oct 07 '22 00:10

juanchopanza