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.
Bookmark this question. Show activity on this post. Derived class should inherit all ctors of base except the default ctor (it is explained here).
Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.
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.
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.
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.
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With