Initialize Base Class with No Default Constructor in Constructor of Derived Class

Initialize base class with no default constructor in constructor of derived class

Because you don't have a default constructor the compiler complains that it can't create an object for primary, you should either add a parameter to the secondary constructor / give it a default value:

class secondary : public primary
{
public:
secondary(int x);
virtual ~secondary();
protected:
private:
};

And then call the base class constructor:

secondary::secondary(int x) : primary(x)
{
//ctor
}

Or:

secondary::secondary() : primary(5)
{
//ctor
}

Or just add a default constructor for primary:

class primary
{
public:
primary(int x);
primary() : primary_x(0) {}
virtual ~primary();
protected:
private:
int primary_x;
};

Error : base class constructor must explicitly initialize parent class constructor

The parent class has an explicit constructor, so compiler will not add an implicit 'empty' constructor to it. Additionally your constructor has a parameter, so compiler can not generate an implicit call to it. That's why you must do it explicitly.

This way:

 child::child(int a) : parent(a)
{
}

Base class don't have default constructor when derived class constructor initialization lists

A default constructor won't be generated if at least a user-defined constructor exists. And in your case, you have one.

Constructor to initialize base part of derived class by object of another derived class

  1. Pointer to Derived1 + dynamic_cast + base class copy-constructor within initializer list

There is no need for pointers, no need for dynamic casting, and no need to limit the argument to only Derived1.


  1. Reference to Base and cast Derived1 when calling

This is fine, except the cast is redundant. An object is implicitly convertible to its base.


  1. Call default constructor of Base first and then initialize every single member

This is pointlessly complicated, and will not be an option in cases where base is not default initialisable.


Another alternative is to pass the base by value, and move from it:

Derived2(Base base) : Base(std::move(base))

This allows avoiding a copy from rvalue arguments. That won't be particularly useful for the trivial Base in the example, but can be much faster for some real example that is slow to copy.

Class inherited from class without default constructor

The constructor should look like this:

A(int i) : B(i) {}

The bit after the colon means, "initialize the B base class sub object of this object using its int constructor, with the value i".

I guess that you didn't provide an initializer for B, and hence by default the compiler attempts to initialize it with the non-existent no-args constructor.

What are the rules for calling the base class constructor?

Base class constructors are automatically called for you if they have no argument. If you want to call a superclass constructor with an argument, you must use the subclass's constructor initialization list. Unlike Java, C++ supports multiple inheritance (for better or worse), so the base class must be referred to by name, rather than "super()".

class SuperClass
{
public:

SuperClass(int foo)
{
// do something with foo
}
};

class SubClass : public SuperClass
{
public:

SubClass(int foo, int bar)
: SuperClass(foo) // Call the superclass constructor in the subclass' initialization list.
{
// do something with bar
}
};

More info on the constructor's initialization list here and here.

What happens if you don't call a base class's constructor for different derived constructors with different signatures?

Quoting from cppreference's description of constructors and how inheritance relates to them:

Before the compound statement that forms the function body of the constructor begins executing, initialization of all direct bases, virtual bases, and non-static data members is finished. Member initializer list is the place where non-default initialization of these objects can be specified. For bases and non-static data members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified. No initialization is performed for anonymous unions or variant members that do not have a member initializer.

(Emphasis added.)

If you do not specify an initialization of the base class subobject in your derived class's constructor's member initializer list, the base class subobject is default-initialized.

Base class default constructor in derived class constructor initializer list

It depends on declaration of base class. Constructor of derived class actually initializes base class. It involves default constructor call if such is present. If base class is trivial, it wouldn't be initialized. Consider this code:

#include <iostream>

struct Base {
int c;
};

class Derived : public Base {
public:
Derived() : Base()
{}
};

int main()
{
Derived d;
std::cout << d.c << std::endl;
}

If you would comment : Base() out, you may get compiler warning, or a random value printed.

prog.cc: In function 'int main()':
prog.cc:17:20: warning: 'd.Derived::<anonymous>.Base::c' is used uninitialized [-Wuninitialized]
17 | std::cout << d.c << std::endl;
| ^
prog.cc:16:13: note: 'd' declared here
16 | Derived d;

in this case : Base() ensures value initialization of Base

constructor of base class is called while declaring a derived class

You have a constructor in the base class that requires two parameters but no default constructor. My guess is that your derived class does not declare constructors so the compiler is trying to create a default for you. It then has no way of calling the base constructor as the only one it has required 2 params.



Related Topics



Leave a reply



Submit