Copy constructor | Sololearn: Learn to code for FREE!
New course! Every coder should learn Generative AI!
Try a free lesson
+ 1

Copy constructor

As we know below signature of copy constructor for class T: T (const T& t) We are passing the object as reference or else we would go into infinite recursion. This we can observe by pasing object as value rather than as reference in copy constructor definition & calling copy constructor from main. Another thing is const.We generally provide const reference to take care of lvalue and rvalue being passed as argument.Simply putting object as ref (without const) would only allow lvalue to be passed as argument for copy constructor and rvalue as argument is not allowed. I hope this info is correct. Plz correct if I am wrong. Now, my query is as below: Refer below code and let me know how to call copy constructor with r value to get compiler error as I have not provided const into copy constructor definition. https://code.sololearn.com/cB9jNDP0FN3x/?ref=app I know const means we should not change existing object also. But I hope that purpose is not the reason for const.

29th May 2020, 8:30 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
12 Answers
+ 1
the "const" is important. 1 - to ensure that the source are not accidentally modified. 2- to allow rvalue to be bound, but only if there is not a more attractive rvalue reference in the overload set. 3- to be able to create a copy of the named objects which happen to be const.
31st May 2020, 9:59 PM
MO ELomari
+ 2
If I'm getting you right,you want to be able to call a constructor with an rvalue as its argument?
29th May 2020, 8:38 PM
Anthony Maina
Anthony Maina - avatar
+ 2
That's quite simple if you've ever heard of rvalue references. So rvalue references are just that ,,,references to rvalues Therefore in your case,you'll have to declare another constructor that takes an rvalue reference argument like this Test(Test&& obj); The two ampersands are used to denote the rvalue nature of the parameter I would like to also add that after doing so,the constructor you've just declared is no longer called a copy constructor but rather a move constructor since they are used to implement move semantics( a notion introduced in C++11 that seeks to reduce runtime and the space utilised by a program by mainly reducing the number of unnecessary copies made) But due to limited time and space I cannot thoroughly discuss this topic here.However there are a tonne of resources out there in the web that discuss this to some great detail.Feel free to check them out
29th May 2020, 10:26 PM
Anthony Maina
Anthony Maina - avatar
+ 1
Sorry as my code misleaded you.... I commented actual copy constructor and removed const from copy constructor.. Now you got it right... How I can call constructor with r value as argument... Yes it would not compile due to missing const keyword but that is what I want to observe
29th May 2020, 10:03 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
+ 1
And another question I got while trying out different thing is as below : Instead of Test T2(T1); I am doing below Test T2(Test()); And copy constructor is not called at all.... Is it no more copy constructor case ?
29th May 2020, 10:09 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
+ 1
i agree with Anthony Maina you'll have to declare another constructor that takes an rvalue reference argument. even with this constructor you'll notice that the same result is printed, this is due to elision of copy operation. https://en.wikipedia.org/wiki/Copy_elision because whenever a temporary object is created for the sole purpose of being copied and subsequently destroyed, the compiler is allowed to remove the temporary object entirely and construct the result directly in the object that is supposed to receive the copy.(this is one of the few instances where C++ is allowed to change program behavior for an optimization) with copy elision disabled → https://godbolt.org/z/bb93dR with copy elision enabled ( by default ) → https://godbolt.org/z/YsfLmK
30th May 2020, 12:46 AM
MO ELomari
+ 1
the following line "Test T2(Test());" is simply an example of the C++'s most vexing parse. I'm sure you think its a variable declaration when the fact its a function declaration. the name of the function is "T2"; the function returns an object of type "Test" and takes a single (unnamed) argument which in turn is a function returning type "Test" and taking no argument. ( comes from C++’s rule that anything that can be parsed as a declaration must be interpreted as one ) https://code.sololearn.com/cyoFPTfYIIFc/#cpp more about C++’s most vexing parse → https://en.wikipedia.org/wiki/Most_vexing_parse
30th May 2020, 1:40 AM
MO ELomari
+ 1
Mohamed ELomari yeah I know how annoying that can be and the subtle bugs it can cause. And as a result I almost always use curly brackets when initializing variables to avoid surprises
30th May 2020, 7:21 AM
Anthony Maina
Anthony Maina - avatar
0
Okay I got your point Mohamed ELomari and Anthony Maina . It helped also me to enhance understanding.. However , I do have still a question why we have const reference as argument of copy constructor. I thought it was for allowing rvalue as copy constructor argument while calling it, but seems it is incorrect... So, const is just to ensure that object we are copying from should not be modified by copy constructor? I was challenged on this answer and hence I am confused and trying to dig into more detail
31st May 2020, 5:20 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
Exactly.It is meant to ensure that you don't modify the object being copied
31st May 2020, 5:26 PM
Anthony Maina
Anthony Maina - avatar
0
Thanks Mohamed ELomari ... I got your first and third point... Could you please elaborate second point may be by example code if possible
1st Jun 2020, 3:45 AM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
with rvalue reference overload → https://godbolt.org/z/2NLLTe without rvalue reference overload → https://godbolt.org/z/q9DJdo the rules for overload resolution are: rvalues will prefer rvalue references ( if it exists in the overload set ) . CV qualification conversions are considered secondary relative to r/l-value conversions. but they can still bind to a const lvalue reference (const A&) unless there is not a more attractive rvalue reference overload (A&&).
1st Jun 2020, 12:19 PM
MO ELomari