Nayana Adassuriya
Nayana Adassuriya

Reputation: 24766

Copy constructor not calling

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

Answers (2)

Alok Save
Alok Save

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

Upvotes: 5

Luchian Grigore
Luchian Grigore

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

Related Questions