why copy constructor is call when we pass an object as an argument by value to a method

爱⌒轻易说出口 提交于 2019-12-28 06:30:31

问题


i am new to C++ programming, when i am doing some C++ programs i have got a doubt that is why copy constructor is called when i pass an object as argument by value to a function. please see my below code in that i am passing a object of class as an argument by value to a function display() but it calling copy constructor and then control is hitting the display() function but i am understanding why it so please help.

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

回答1:


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 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 wether 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).




回答2:


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.




回答3:


As juanchopanza said:, you pass by value, which causes a copy to be made. If you want to prevent this you can pass by reference:

void display(const ClassA &obj)

On a sidenote: You should declare your copy ctor to take the argument as const reference:

ClassA(const ClassA &obj)

Otherwise you won't be able to use the copy ctor on named objects marked as const or with temporaries. It also prevents you from accidentally changing the passed in object.



来源:https://stackoverflow.com/questions/16728441/why-copy-constructor-is-call-when-we-pass-an-object-as-an-argument-by-value-to-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!