Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Parameters to Base Class Constructors C++

I like to keep my class declarations and definitions separate in C++. So, in a header I may define a 'base' class as follows:

# Base.h
class Base 
{
    int n;    
public:
    Base(int x);
};

and define its constructor implementation in a cpp file, i.e.,

# Base.c
Base::Base(int x) 
{
    n = x;
}

Now, if I define a 'derived' class that inherits the 'base' class, I can pass parameters to the base class as follows:

#Derived.h
class Derived : public Base
{
    int t;
public:
    Derived(int y) : Base(t) {t = y;}
}

But doing it this way requires that I place the body of the constructor for the Derived class in the header file, i.e., {t = y;}, and thus the constructor definition is no longer separate from its declaration. Is there a way to pass arguments to a class's base class constructor that still enables me to define the constructor for the derived class in a cpp file?

like image 749
James B Avatar asked Sep 19 '25 12:09

James B


2 Answers

Yes there is, in the header file:

class Derived : public Base
{
    int t;
public:
    Derived(int y); // Declaration of constructor
};

while in the cpp file:

Derived::Derived(int y) : Base(t) { // Definition of constructor
    t = y;
}

Member initializer lists are allowed in the definition of a class constructor as well as in inline in-class definitions. In case you're interested, I also recommend to take a look at cppreference for two small caveats regarding the order of initialization and the fact that members will be initialized before the compound constructor body is executed.

like image 79
Marco A. Avatar answered Sep 21 '25 01:09

Marco A.


Is there a way to pass arguments to a class's base class constructor that still enables me to define the constructor for the derived class in a cpp file?

Of course there is. The header can just declare the constructor, exactly as you did for Base:

class Derived : public Base
{
    int t;
public:
    Derived(int y);
};

then you can implement that in a source file, exactly as you did for Base:

Derived::Derived(int y) : Base(y), t(y) {}

Note that you'll have to pass the argument y, not the (as yet uninitialised) member t to the base constructor. Base sub-objects are always initialised before members.

like image 23
Mike Seymour Avatar answered Sep 21 '25 01:09

Mike Seymour