简体   繁体   中英

C++ Why was the copy constructor called?

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?

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.

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 ) {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM