4
class A { public: A() {} A(const A& a) { cout << "A::A(A&)" << endl; } }; class B { public: explicit B(A aa) {} }; int main() { A a; B b(a); return 0; } 

Why does it print "A::A(A&)"?

When was the copy constructor for "A" called? And if the code calls the copy constructor, why can I remove the copy constructor without creating a compilation error?

2 Answers 2

14

B(A aa) takes an A by value, so when you execute B b(a) the compiler calls the copy constructor A(const A& a) to generate the instance of A named aa in the explicit constructor for B.

The reason you can remove the copy constructor and have this still work is that the compiler will generate a copy constructor for you in cases where you have not also declared a move constructor.

Note: The compiler generated copy constructor is often not sufficient for complex classes, it performs a simple member wise copy, so for complex elements or dynamically allocated memory you should declare your own.

§ 15.8.1

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (11.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor or assignment operator.

Sign up to request clarification or add additional context in comments.

1 Comment

The compiler generated copy constructor should have no problem with "complex elements", if said elements are of a type that has been written correctly.
7

Why the copy happens

Look at your class B c'tor:

class B { public: explicit B(A aa) {} }; 

You receive A by value, triggering a copy during the call.

If you would have change it to (notice A & aa):

class B { public: explicit B(A & aa) {} }; 

There wouldn't be any copy...

Default copy constructor

When you remove the c'tor, the compiler generates one for you when it can trivially do so:

First, you should understand that if you do not declare a copy constructor, the compiler gives you one implicitly. The implicit copy constructor does a member-wise copy of the source object.

The default c'tor is equivalent to:

MyClass::MyClass( const MyClass& other ) : x( other.x ), c( other.c ), s( other.s ) {} 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.