How do I call the base class constructor?

C++Constructor

C++ Problem Overview


Lately, I have done much programming in Java. There, you call the class you inherited from with super(). (You all probably know that.)

Now I have a class in C++, which has a default constructor which takes some arguments. Example:

class BaseClass {
public:
	BaseClass(char *name); .... 

If I inherit the class, it gives me the warning that there is no appropriate default constructor available. So, is there something like super() in C++, or do I have to define a function where I initialize all variables?

C++ Solutions


Solution 1 - C++

You do this in the initializer-list of the constructor of the subclass.

class Foo : public BaseClass {
public:
    Foo() : BaseClass("asdf") {}
};

Base-class constructors that take arguments have to be called there before any members are initialized.

Solution 2 - C++

In the header file define a base class:

class BaseClass {
public:
    BaseClass(params);
};

Then define a derived class as inheriting the BaseClass:

class DerivedClass : public BaseClass {
public:
    DerivedClass(params);
};

In the source file define the BaseClass constructor:

BaseClass::BaseClass(params)
{
     //Perform BaseClass initialization
}

By default the derived constructor only calls the default base constructor with no parameters; so in this example, the base class constructor is NOT called automatically when the derived constructor is called, but it can be achieved simply by adding the base class constructor syntax after a colon (:). Define a derived constructor that automatically calls its base constructor:

DerivedClass::DerivedClass(params) : BaseClass(params)
{
     //This occurs AFTER BaseClass(params) is called first and can
     //perform additional initialization for the derived class
}

The BaseClass constructor is called BEFORE the DerivedClass constructor, and the same/different parameters params may be forwarded to the base class if desired. This can be nested for deeper derived classes. The derived constructor must call EXACTLY ONE base constructor. The destructors are AUTOMATICALLY called in the REVERSE order that the constructors were called.

EDIT: There is an exception to this rule if you are inheriting from any virtual classes, typically to achieve multiple inheritance or diamond inheritance. Then you MUST explicitly call the base constructors of all virtual base classes and pass the parameters explicitly, otherwise it will only call their default constructors without any parameters. See: https://stackoverflow.com/questions/16945465/virtual-inheritance-skipping-constructors

Solution 3 - C++

You have to use initiailzers:

class DerivedClass : public BaseClass
{
public:
  DerivedClass()
    : BaseClass(<insert arguments here>)
  {
  }
};

This is also how you construct members of your class that don't have constructors (or that you want to initialize). Any members not mentioned will be default initialized. For example:

class DerivedClass : public BaseClass
{
public:
  DerivedClass()
    : BaseClass(<insert arguments here>)
    , nc(<insert arguments here>)
    //di will be default initialized.
  {
  }

private:
  NeedsConstructor nc;
  CanBeDefaultInit di;
};

The order the members are specified in is irrelevant (though the constructors must come first), but the order that they will be constructed in is in declaration order. So nc will always be constructed before di.

Solution 4 - C++

Regarding the alternative to super; you'd in most cases use use the base class either in the initialization list of the derived class, or using the Base::someData syntax when you are doing work elsewhere and the derived class redefines data members.

struct Base
{
	Base(char* name) { }
	virtual ~Base();
	int d;
};

struct Derived : Base
{
	Derived() : Base("someString") { }
	int d;
	void foo() { d = Base::d; }
};

Solution 5 - C++

Use the name of the base class in an initializer-list. The initializer-list appears after the constructor signature before the method body and can be used to initialize base classes and members.

class Base
{
public:
  Base(char* name)
  {
     // ...
  }
};

class Derived : Base
{
public:
  Derived()
    : Base("hello")
  {
      // ...
  }
};

Or, a pattern used by some people is to define 'super' or 'base' yourself. Perhaps some of the people who favour this technique are Java developers who are moving to C++.

class Derived : Base
{
public:
  typedef Base super;
  Derived()
    : super("hello")
  {
      // ...
  }
};

Solution 6 - C++

There is no super() in C++. You have to call the Base Constructor explicitly by name.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStefanView Question on Stackoverflow
Solution 1 - C++Björn PollexView Answer on Stackoverflow
Solution 2 - C++MasterHDView Answer on Stackoverflow
Solution 3 - C++Nicol BolasView Answer on Stackoverflow
Solution 4 - C++Seb HolzapfelView Answer on Stackoverflow
Solution 5 - C++Scott LanghamView Answer on Stackoverflow
Solution 6 - C++Shamim Hafiz - MSFTView Answer on Stackoverflow