Why does my C++ subclass need an explicit constructor?
Solution 1
All the derived classes must call their base class's constructor in some shape or form.
When you create an overloaded constructor, your default compiler generated parameterless constructor disappears and the derived classes must call the overloaded constructor.
When you have something like this:
class Class0 {
}
class Class1 : public Class0 {
}
The compiler actually generates this:
class Class0 {
public:
Class0(){}
}
class Class1 : public Class0 {
Class1() : Class0(){}
}
When you have non-default constructor, the parameterless constructor is no longer generated. When you define the following:
class Class0 {
public:
Class0(int param){}
}
class Class1 : public Class0 {
}
The compiler no longer generates a constructor in Class1 to call the base class's constructor, you must explicitly do that yourself.
Solution 2
Constructors are not inherited. You have to create a constructor for the derived class. The derived class's constructor, moreover, must call the base class's constructor.
Solution 3
You have to construct your base class before dealing with derived. If you construct your derived class with non-trivial constructors, compiler cannot decide what to call for base, that's why error is occuring.
Neil Steiner
[For my personal use: https://userstyles.org/styles/98190/hide-stack-exchange-hot-network-questions]
Updated on June 05, 2022Comments
-
Neil Steiner about 2 years
I have a base class that declares and defines a constructor, but for some reason my publicly derived class is not seeing that constructor, and I therefore have to explicitly declare a forwarding constructor in the derived class:
class WireCount0 { protected: int m; public: WireCount0(const int& rhs) { m = rhs; } }; class WireCount1 : public WireCount0 {}; class WireCount2 : public WireCount0 { public: WireCount2(const int& rhs) : WireCount0(rhs) {} }; int dummy(int argc, char* argv[]) { WireCount0 wireCount0(100); WireCount1 wireCount1(100); WireCount2 wireCount2(100); return 0; }
In the above code, my
WireCount1 wireCount1(100)
declaration is rejected by the compiler ("No matching function for call to 'WireCount1::WireCount1(int)'"), while mywireCount0
andwireCount2
declarations are fine.I'm not sure that I understand why I need to provide the explicit constructor shown in
WireCount2
. Is it because the compiler generates a default constructor forWireCount1
, and that constructor hides theWireCount0
constructor?For reference, the compiler is
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659)
. -
Shirik almost 14 yearsI think you misread his question. He isn't asking why he can't call Class1's default constructor, but rather why there is no Class1(int) constructor to call.
-
In silico almost 14 yearsAlso, if the base class has a default constructor, then the compiler will use that one if you don't explicitly specify a constructor in the initializer list of a constructor in the derived class.
-
Johannes Schaub - litb almost 14 yearsThe compiler still generates a
Class1()
constructor in your last example. It's just that this constructor is ill-formed if it's actually defined (by default as for all special functions, it's only declared until it's actually used). You can verify this by making it a friend:class Class2 { friend Class1::Class1(); };
, which works because the compiler implicitly declares the default constructor no matter whether it could actually be called. -
Neil Steiner almost 14 yearsThanks. I didn't realize that constructors were never inherited. I had convinced myself that other base class constructors (in the real code) were in fact visible, but I now attribute that to a bunch of casting that the compiler may have been doing.
-
Neil Steiner almost 14 yearsThanks. That makes it very clear to me. Although I appreciate Shirik's response, I believe your example shows exactly what's been happening in my code.
-
Neil Steiner almost 14 yearsI regret that as a newbie, I don't yet have enough reputation points to bump up your answer.
-
Igor Zevaka almost 14 years@Johannes Schaub - litb Thanks for that, I didn't know that.
-
Manuel Arwed Schmidt about 10 yearsTheres a discussion about this at stackoverflow.com/questions/22951260/… , FYI
-
Jonny over 8 yearsI thought I could go home early... now I have to work overtime, filling in the exact same lines of code in my subclasses.