After using C# for the past decade or two, my C++ has gone a little rusty.
If I have the following:
class CBase
{
public:
CBase(LPCTSTR pszArg1, LPCTSTR pszArg2, LPCTSTR pszArg3);
virtual ~CBase();
// Etc...
};
class CDerived : CBase
{
// Etc...
};
It appears I cannot create an instance of CDerived
.
no instance of constructor "CDerived::CDerived" matches the argument list
I know I can create a derived constructor explicitly:
CDerived::CDerived(LPCTSTR pszArg1, LPCTSTR pszArg2, LPCTSTR pszArg3)
: CBase(pszArg1, pszArg2, pszArg3)
{
}
But that seems like a lot of typing, particularly if I plan to derive many classes from the base class.
The base class still needs those arguments one way or another. Is there a way to not have to rewrite this arguments for every derived class, "exposing" the base constructor perhaps, or must I absolutely always do as I've done above?
When constructing a derived class, the derived class constructor is responsible for determining which base class constructor is called. If no base class constructor is specified, the default base class constructor will be used.
Base class constructors are always called using the derived class constructors. Whenever you create derived class object, first the base class default constructor is executed and then the derived class’s constructor finishes execution. In inheritance constructor of base class is inherited like other member functions.
What's more, we can explicitly call the base class constructor in the child class constructor. A base class is also called a " superclass ". That's why Java uses the keyword super to indicate the base class. In the previous example public Cat(String brain, String heart, String tail) { this. brain = brain; this. heart = heart; this. tail = tail; }
All that’s happening is that the Derived constructor is calling a specific Base constructor to initialize the Base portion of the object. Because m_id lives in the Base portion of the object, the Base constructor is the only constructor that can initialize that value.
You could use inheriting constructors (since C++11):
class CDerived : public CBase
{
public:
using CBase::CBase;
// Etc...
};
Then you could
LPCTSTR pszArg1;
LPCTSTR pszArg2;
LPCTSTR pszArg3;
CDerived d(pszArg1, pszArg2, pszArg3); // initialize CBase subobject by CBase::CBase(LPCTSTR, LPCTSTR LPCTSTR),
// then default-initialize other members of CDerived
Yes, you can do that in C++11 and later. To inherit a base constructor, you must use the using
keyword followed by the name of the base class constructor:
struct CBase {
CBase(LPCTSTR pszArg1, LPCTSTR pszArg2, LPCTSTR pszArg3);
virtual ~CBase();
// Etc...
};
struct CDerived : CBase {
// we use the base constructor
using CBase::CBase;
};
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