In which situations is the C++ copy constructor called?

34,183

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

Share:
34,183
Pandrei
Author by

Pandrei

Updated on July 13, 2022

Comments

  • Pandrei
    Pandrei almost 2 years

    I know of the following situations in c++ where the copy constructor would be invoked:

    1. when an existing object is assigned an object of it own class

      MyClass A,B;
      A = new MyClass();
      B=A; //copy constructor called 
      
    2. if a functions receives as argument, passed by value, an object of a class

      void foo(MyClass a);
      foo(a); //copy constructor invoked
      
    3. 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.