PP.
PP.

Reputation: 10864

Does C++ optimise construction-and-copy into a copy constructor?

Does a C++ compiler automatically convert:

MyObject object2 = object1;

into

MyObject object2( object1 );

?

Or does it treat it like:

MyObject object2;
object2 = object1;

?

Upvotes: 3

Views: 234

Answers (4)

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234474

What gets called with MyObject object2 = object1; is a constructor because this is initialization. This has nothing to do with the assignment operator.

However, the transformation you suggested from MyObject object2 = object1; into MyObject object2(object1); does not happen, because these two initialization syntaxes are not the same. They are similar in that they both initialize an object by calling a constructor, but they have a slight difference.

If you have:

struct MyObject {
    explicit MyObject(MyObject const&);
};

Then MyObject object2 = object1; is ill-formed, but MyObject object2(object1); is well-formed.

Upvotes: 2

jweyrich
jweyrich

Reputation: 32240

You can try this to see the exact behavior:

#include <iostream>

class MyObject {
public:
    MyObject() {
        std::cout << "MyObject()" << std::endl;
    }
    MyObject(const MyObject& other) {
        std::cout << "MyObject(const MyObject& other)" << std::endl;
    }
    MyObject& operator=(const MyObject& other) {
        std::cout << "operator=(const MyObject& other)" << std::endl;
        return *this;
    }
};

int main() {
    MyObject object1;
    MyObject object2 = object1;
    MyObject object3(object1);
    MyObject object4;
    object4 = object1;
}

Outputs:

MyObject()
MyObject(const MyObject& other)
MyObject(const MyObject& other)
MyObject()
operator=(const MyObject& other)

Apart from that, I recommend reading What is The Rule of Three?

Upvotes: 2

Anthony Williams
Anthony Williams

Reputation: 68591

MyObject object2 = object1;

is copy-initialization. This will call the copy constructor, if object1 is of type MyObject.

If object1 is of a different type then it will either do an implicit conversion from object1 to MyObject, and then either copy-construct object2 from that, or do the implicit conversion directly into object2 and skip the copy construction. The copy constructor (or move constructor in C++11) must be accessible in both cases.

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272507

Yes, it's the first one. It's not an "optimisation"; they are two different syntaxes for invoking the copy constructor.

If you want to prove it, try defining a private assignment operator for MyObject. The code should still compile, which proves it can't be equivalent to the second mechanism.

Upvotes: 8

Related Questions