In which situations is the C++ copy constructor called?
Solution 1
I might be wrong about this, but this class allows you to see what is called and when:
class a {
public:
a() {
printf("constructor called\n");
};
a(const a& other) {
printf("copy constructor called\n");
};
a& operator=(const a& other) {
printf("copy assignment operator called\n");
return *this;
};
};
So then this code:
a b; //constructor
a c; //constructor
b = c; //copy assignment
c = a(b); //copy constructor, then copy assignment
produces this as the result:
constructor called
constructor called
copy assignment operator called
copy constructor called
copy assignment operator called
Another interesting thing, say you have the following code:
a* b = new a(); //constructor called
a* c; //nothing is called
c = b; //still nothing is called
c = new a(*b); //copy constructor is called
This occurs because when you when you assign a pointer, that does nothing to the actual object.
Solution 2
When an existing object is assigned an object of it own class
B = A;
Not necessarily. This kind of assignment is called copy-assignment, meaning the assignment operator of the class will be called to perform memberwise assignment of all the data members. The actual function is MyClass& operator=(MyClass const&)
The copy-constructor is not invoked here. This is because the assignment operator takes a reference to its object, and therefore no copy-construction is performed.
Copy-assignment is different from copy-initialization because copy-initialization is only done when an object is being initialized. For example:
T y = x;
x = y;
The first expression initializes y
by copying x
. It invokes the copy-constructor MyClass(MyClass const&)
.
And as mentioned, x = y
is a call to the assignment operator.
(There is also something called copy-elison whereby the compiler will elide calls to the copy-constructor. Your compiler more than likely uses this).
If a functions receives as argument, passed by value, an object of a class
void foo(MyClass a); foo(a);
This is correct. However, note that in C++11 if a
is an xvalue and if MyClass
has the appropriate constructor MyClass(MyClass&&)
, a
can be moved into the parameter.
(The copy-constructor and the move-constructor are two of the default compiler-generated member functions of a class. If you do not supply them yourself, the compiler will generously do so for you under specific circumstances).
When a function returns (by value) an object of the class
MyClass foo () { MyClass temp; .... return temp; // copy constructor called }
Through return-value optimization, as mentioned in some of the answers, the compiler can remove the call to the copy-constructor. By using the compiler option -fno-elide-constructors
, you can disable copy-elison and see that the copy-constructor would indeed be called in these situations.
Solution 3
Situation (1) is incorrect and does not compile the way you've written it. It should be:
MyClass A, B;
A = MyClass(); /* Redefinition of `A`; perfectly legal though superfluous: I've
dropped the `new` to defeat compiler error.*/
B = A; // Assignment operator called (`B` is already constructed)
MyClass C = B; // Copy constructor called.
You are correct in case (2).
But in case (3), the copy constructor may not be called: if the compiler can detect no side effects then it can implement return value optimisation to optimise out the unnecessary deep copy. C++11 formalises this with rvalue references.
Solution 4
This is basically correct (other than your typo in #1).
One additional specific scenario to watch out for is when you have elements in a container, the elements may be copied at various times (for example, in a vector, when the vector grows or some elements are removed). This is actually just an example of #1, but it can be easy to forget about it.
Solution 5
There are 3 situations in which the copy constructor is called: When we make copy of an object. When we pass an object as an argument by value to a method. When we return an object from a method by value.
these are the only situations....i think...
Pandrei
Updated on July 13, 2022Comments
-
Pandrei almost 2 years
I know of the following situations in c++ where the copy constructor would be invoked:
when an existing object is assigned an object of it own class
MyClass A,B; A = new MyClass(); B=A; //copy constructor called
if a functions receives as argument, passed by value, an object of a class
void foo(MyClass a); foo(a); //copy constructor invoked
when a function returns (by value) an object of the class
MyClass foo () { MyClass temp; .... return temp; //copy constructor called }
Please feel free to correct any mistakes I've made; but I am more curious if there are any other situations in which the copy constructor is called.