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

后端 未结 7 1657
梦毁少年i
梦毁少年i 2020-12-23 02:06

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

相关标签:
7条回答
  • 2020-12-23 02:41

    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.

    0 讨论(0)
  • 2020-12-23 02:42

    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.

    0 讨论(0)
  • 2020-12-23 02:52

    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.

    0 讨论(0)
  • 2020-12-23 02:55

    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.

    0 讨论(0)
  • 2020-12-23 02:58

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

    0 讨论(0)
  • 2020-12-23 03:03

    The following are the cases when copy constructor is called.

    1. When instantiating one object and initializing it with values from another object.
    2. When passing an object by value.
    3. When an object is returned from a function by value.
    0 讨论(0)
提交回复
热议问题