Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 561
Vincenzo Pii Avatar asked Feb 07 '12 14:02

Vincenzo Pii


People also ask

When copy constructor is implicitly called?

A copy constructor is a member function that initializes an object using another object of the same class. The Copy constructor is called mainly when a new object is created from an existing object, as a copy of the existing object.

When copy constructor is used implicitly for what purpose?

A user-defined copy constructor is generally needed when an object owns pointers or non-shareable references, such as to a file, in which case a destructor and an assignment operator should also be written (see Rule of three).

Why argument to a copy constructor must be passed as a reference?

It is necessary to pass object as reference and not by value because if you pass it by value its copy is constructed using the copy constructor. This means the copy constructor would call itself to make copy. This process will go on until the compiler runs out of memory.

What happens if a user forgets to define a constructor inside a class?

What happens if a user forgets to define a constructor inside a class? Explanation: The C++ compiler always provides a default constructor if one forgets to define a constructor inside a class.


1 Answers

All base child constructors call the parent default constructor. This is how the standard is defined. As you pointed out if you wanted the derive class B to call A's copy constructor you have to explicitly ask for it

#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):A(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; } 

This is so because the compiler can't know for each different constructor which constuctor of the parent should be called and hence we have the default constructors For all others you have to explicitly state them.

Output:

Creating B A::Default constructor B::Default constructor Creating B by copy A::Copy constructor B::Copy constructor 
like image 70
Lefteris Avatar answered Sep 29 '22 08:09

Lefteris