开发者

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

开发者 https://www.devze.com 2023-03-30 23:33 出处:网络
Does a C++ compiler automatically convert: 开发者_运维百科MyObject object2 = object1; into MyObject object2( object1 );

Does a C++ compiler automatically convert:

开发者_运维百科
MyObject object2 = object1;

into

MyObject object2( object1 );

?

Or does it treat it like:

MyObject object2;
object2 = object1;

?


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.


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?


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消