Copy constructor not calling

Deadly 提交于 2019-12-22 08:59:09

问题


When I read about copy initializing vs direct initializing here. copy constructor should call in copy initializing. why here copy constructor not calling?

#include <iostream>

using namespace std;

class A{};

class B{
public:
B(const A &a){cout << "B construct from A" << endl;}
B(const B &b){cout << "B copy constructor" << endl;}
};

int main(){
A a;
B b = a;
return 0;
}

回答1:


This is Copy ElisionRef 1:.
Copy constructor calls while generating temporaries might be optimized by the compiler by creating objects inline and it is explicitly allowed by the C++ Standard.

This is nicely demonstrated in the standard with an example as well:

C++03 Standard 12.2 Temporary objects [class.temporary]
Para 2:

[Example:
class X {
    // ...
    public:
    // ...
    X(int);
    X(const X&);
    ˜X();
};
X f(X);

void g()
{
    X a(1);
    X b = f(X(2));
    a = f(a);
}

Here, an implementation might use a temporary in which to construct X(2) before passing it to f() using X’s copy-constructor; alternatively, X(2) might be constructed in the space used to hold the argument. Also, a temporary might be used to hold the result of f(X(2)) before copying it to `b usingX’s copyconstructor; alternatively,f()’s result might be constructed in b. On the other hand, the expressiona=f(a)requires a temporary for either the argument a or the result off(a)to avoid undesired aliasing ofa`. ]

Ref 1:
C++03 12.8 Copying class objects [class.copy]
Para 12:

When certain criteria are met, an implementation is allowed to omit the copy construction of a class object, even if the copy constructor and/or destructor for the object have side effects.....




回答2:


Copy initialization is still subject to copy elision, and I'm guessing that's what's happening. Theoretically, a temporary B is constructed from a and the the copy constructor is used to create b from the temporary. In practice, the copy can be optimized out.

To test this, you can make the copy constructor private:

class B{
public:
B(const A &a){cout << "B construct from A" << endl;}
private:
B(const B &b){cout << "B copy constructor" << endl;}
};

and get a compilation error. This means the compiler expects the copy constructor to be accessible, but is not required to call it.

Copy elision is the only case where observed behavior can be altered.



来源:https://stackoverflow.com/questions/12686099/copy-constructor-not-calling

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!