Reputation: 24766
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;
}
Upvotes: 4
Views: 274
Reputation: 206508
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 tof()
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 off(X(2))
before copying it to`b using
X’s copyconstructor; alternatively,
f()’s result might be constructed in b. On the other hand, the expression
a=f(a)requires a temporary for either the argument a or the result of
f(a)to avoid undesired aliasing of
a`. ]
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.....
Upvotes: 5
Reputation: 258548
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.
Upvotes: 5