Search code examples
c++language-designcopy-constructor

Why does the implicit copy constructor calls the base class copy constructor and the defined copy constructor doesn't?


Consider a class hierarchy where A is the base class and B derives from A.

If the copy constructor is not defined in B, the compiler will synthesize one. When invoked, this copy constructor will call the base class copy constructor (even the synthesized one, if none has been provided by the user).

#include <iostream>

class A {
    int a;
public:
    A() {
        std::cout << "A::Default constructor" << std::endl;
    }

    A(const A& rhs) {
        std::cout << "A::Copy constructor" << std::endl;
    }
};

class B : public A {
    int b;
public:
    B() {
        std::cout << "B::Default constructor" << std::endl;
    }
};

int main(int argc, const char *argv[])
{
    std::cout << "Creating B" << std::endl;
    B b1;
    std::cout << "Creating B by copy" << std::endl;
    B b2(b1);
    return 0;
}

Output:

Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Copy constructor

If the user defines its own copy constructor in B, when invoked, this copy constructor will call the base class default constructor, unless a call to the base class copy constructor is explicitly present (e.g. in the initialization list).

#include <iostream>

class A {
    int a;
public:
    A() {
        std::cout << "A::Default constructor" << std::endl;
    }

    A(const A& rhs) {
        std::cout << "A::Copy constructor" << std::endl;
    }
};

class B : public A {
    int b;
public:
    B() {
        std::cout << "B::Default constructor" << std::endl;
    }
    B(const B& rhs) {
        std::cout << "B::Copy constructor" << std::endl;
    }
};

int main(int argc, const char *argv[])
{
    std::cout << "Creating B" << std::endl;
    B b1;
    std::cout << "Creating B by copy" << std::endl;
    B b2(b1);
    return 0;
}

Output:

Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Default constructor
B::Copy constructor

My question is, why doesn't the user defined copy constructor call the base class copy constructor as a default behavior?


Solution

  • That's just the way the implicit copy constructor is defined (it wouldn't make sense calling the default). As soon as you define any constructor (copy or otherwise) its normal automatic behavior is to call the default parent constructor, so it would be inconsistent to change that for one specific user-defined constructor.