Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy constructor is not inherited

I've got the following code:

class C {
public:
    C(int) {}
    C(const C&) {}
    C() {}
};  

class D : public C { 
public:
    using C::C;
};  

int main() {
    C c;
    D d_from_c(c); // does not compile, copy ctor is not inherited
    D d_from_int(1); // compiles, C(int) is inherited
}   

Derived class should inherit all ctors of base except the default ctor (it is explained here). But why copy ctor is not inherited as well? Arguments from the related question are not acceptable here.

The code is compiled with g++ 4.8.1.

like image 956
Ivan Smirnov Avatar asked Feb 11 '15 09:02

Ivan Smirnov


People also ask

Are copy constructors inherited?

Bookmark this question. Show activity on this post. Derived class should inherit all ctors of base except the default ctor (it is explained here).

Why constructor is not inherited?

Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

Which constructor Cannot inherit?

A parent class constructor is not inherited in child class and this is why super() is added automatically in child class constructor if there is no explicit call to super or this.

Are constructors inherited in C++?

Constructor is automatically called when the object is created. Multiple Inheritance: Multiple Inheritance is a feature of C++ where a class can derive from several(two or more) base classes. The constructors of inherited classes are called in the same order in which they are inherited.


3 Answers

Because the standard says so. [class.inhctor]/p3, emphasis mine:

For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.

like image 82
T.C. Avatar answered Oct 31 '22 01:10

T.C.


Derived class should inherit all ctors of base except the default ctor

No, that's not true, see T.C.'s answer for the real rule.

The purpose of inheriting constructors is to say "the derived type can be created from the same arguments as the base type", but that isn't relevant for the base class' copy constructor, because a copy constructor is not just a way of saying how to create a type from a given argument.

A copy constructor is special, it's for copying an object of the same type.

A constructor D(const C&) would not used be for copying an object of the same type, because C is not the same type as D.

like image 37
Jonathan Wakely Avatar answered Oct 31 '22 03:10

Jonathan Wakely


For a moment, we’ll assume ‘copy constructor inheritance’ is allowed. Having your class structure intact, please consider following code for modified main method.

int main() {
    C c;
    D d;
    D d_from_d(d);
    D d_from_c(c); // does not compile, copy ctor is not inherited
    D d_from_int(1); // compiles, C(int) is inherited
}  

In D d_from_d(d), as a normal constructor call, there will be two copy constructor calls. One for C::C(const C&) and the other one is for compiler generated copy constructor for D. Having source object type in D (d in this case), C’s copy constructor can copy d’s C attributes while compiler generated D’s copy constructor can copy d’s D attribute.

But in D d_from_c(c) case, There is no problem for C’s copy constructor because, c’s C attributes can be copies by C’s copy constructor. But how does the compiler generated D’s copy constructor know the way to copy ‘D’s attributes from C’s object’. This is a conflict which should be avoided.

But, if you provide some sort of ‘weird copy constructor’ (you may need to a default constructor as well) like;

D(const C & c):C(c){} 

Then, calling D d_from_c(c); is valid. Because, now we have explicitly provided a matching ‘copy’ constructor.

So, saying ‘Inheriting copy constructors are now allowed’ is invalid.

like image 36
Doonyx Avatar answered Oct 31 '22 01:10

Doonyx