Using this hierarchy :
struct TestBase {
// Constructor
TestBase();
TestBase(int a);
TestBase(TestBase const &testBase);
// Destructor
virtual ~TestBase();
};
struct TestChild : public TestBase {
// Constructor inheritance
using TestBase::TestBase;
};
With this test code :
TestBase testBase; // 1) Custom constructor
TestChild testChild; // 2) Default constructor created by the compiler
TestChild testChild2(1); // 3) Inherited from parent with 'using' keyword
TestChild testChild3(testChild); // 4) Default copy constructor created by the compiler ?
TestChild testChild4(testBase); // 5) Doesn't work, why it doesn't inherit ?
First I was thinking that in test 4 the copy constructor was inherited from TestBase (by the 'using' keyword) but in fact it's because the compiler generates a default copy constructor which calls copy constructor of the parent class, is it correct ?
A copy constructor can't be inherited because it must have the same parameter type than the class, is it correct too ?
But why test 5 doesn't compile ? It's not a copy constructor for the TestChild class so it must be inherited, no?
This is the error message:
foo.cpp: In function ‘int main()’:
foo.cpp:21:34: error: no matching function for call to ‘TestChild::TestChild(TestBase&)’
TestChild testChild4(testBase); // 5) Doesn't work, why it doesn't inherit ?
^
foo.cpp:21:34: note: candidates are:
foo.cpp:11:12: note: TestChild::TestChild()
struct TestChild : public TestBase {
^
foo.cpp:11:12: note: candidate expects 0 arguments, 1 provided
foo.cpp:13:25: note: TestChild::TestChild(int)
using TestBase::TestBase;
^
foo.cpp:13:25: note: no known conversion for argument 1 from ‘TestBase’ to ‘int’
foo.cpp:11:12: note: TestChild::TestChild(const TestChild&)
struct TestChild : public TestBase {
^
foo.cpp:11:12: note: no known conversion for argument 1 from ‘TestBase’ to ‘const TestChild&’
foo.cpp:11:12: note: TestChild::TestChild(TestChild&&)
foo.cpp:11:12: note: no known conversion for argument 1 from ‘TestBase’ to ‘TestChild&&’
A using-declaration that names a constructor implicitly declares a set of inherited constructors, but what is worth noting is that there are certain constructs which are not inherited.
12.9 Inheriting Constructors
[class.inhctor]
3 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.
The above sentence might look more cryptic that it actually is.. what it is saying, in simple english, is that a constructor is only inherited in the context of using Base::Base
if the constructor;
Derived
that matches a constructor normally inherited from Base
With the above in mind we realize that the constructor in TestBase
that takes a TestBase const&
is a copy-constructor, and since copy-constructors are not inherited, that's the reason for it being non-present in TestChild
.
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