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

I'm trying to create a subclass secondary which could be used with a parameter as well as it's overriding class primary. Now I get

no matching function to call

error. Could someone help me?

My code:
primary.h:

#ifndef PRIMARY_H
#define PRIMARY_H


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

#endif // PRIMARY_H

primary.cpp:

#include "primary.h"

primary::primary(int x)
{
    primary_x = x;
}

primary::~primary()
{
    //dtor
}

secondary.h:

#ifndef SECONDARY_H
#define SECONDARY_H
#include "primary.h"


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

#endif // SECONDARY_H

secondary.cpp:

#include "secondary.h"

secondary::secondary()
{
    //ctor
}

secondary::~secondary()
{
    //dtor
}

Solution 1:

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;
};

Solution 2:

This whole problem looks like you wanted to do something, but you forgot what it was, in the middle of writing the code.

The constructor of primary expects an int and it's not getting it, because

secondary::secondary() { }

is equivalent to:

secondary::secondary() : primary() { }

Compiler tries to default-construct primary, but it's not default-constructible. Because you declared a constructor taking int, the default constructor is no longer generated by the compiler.

Solutions:

  • modify the derived class' constructor:

    secondary::secondary() : primary(10) { } // dummy value
    

    or mimic the base class constructor's signature:

    secondary::secondary(int x) : primary(x) { }
    
  • modify the base class - make primary default-constructible, i.e. declare constructor as:

    primary(int x = 10) // dummy default argument
    

    or add a default-constructor overload:

    primary() = default;