binyamina
binyamina

Reputation: 193

Preferred way to initialize base class members (c++)

I have a base class:

class Base {
protected:
    int m_a;
    virtual void foo() = 0;
}

And a derived class(es)

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

The base class is abstract, so only derived classes can be created. How is the better way to implement the derived Ctor?

Derived::Derived(int a) : Base(a) {}
Base::Base(int a) : m_a(a) {}

Or

Derived::Derived(int a) { m_a = a;}
Base::Base(){}

Is it better to remove the member from Base constructor, since it cannot be created alone, OR to keep it on the Base constructor to stay the assignment for him?

Upvotes: 4

Views: 1325

Answers (2)

Alexey Usachov
Alexey Usachov

Reputation: 1374

I would prefer :

Derived::Derived(int a) : Base(a) {}
Base::Base(int a) : m_a(a) {}

By this way you make your code more encapsulated and Base members took care about its init list, there can be some more init logic in base class constructor depending on m_a instead of just initing m_a. In this case you pass initial value to your base constructor and then derived class in his constructor has initialized constructor of base class.

You should try to pass init values to your Base class, imagine you have 5 Derived classes and you need to init base class at all of yours derived ctors.

Upvotes: 1

peterchen
peterchen

Reputation: 41106

Your first solution- giving the base class an explicit constructor - is preferable as general pattern:

  • it avoids other classes inherited from Base forgetting to initialize m_a. Instead, the signature of the class indicates initialization is required.

  • if multiple classes inherit from base, and initialization is more complex (e.g. a range check) , this code - and policy - is not distributed over multiple derived classes

  • if m_a is immutable, constructor initialization is required

  • derived classes might have more than one CTor, more places to forget

Only downside: a little more typing - as long as you don't count the additional "I'm a little lazy today so don't forget to init m_a in all derived classes constructors"

The "signature announces the requirements" is IMO sufficient to make this the default pattern, so is "the other way requires making m_a protected", as mentioned in the comments.

Upvotes: 4

Related Questions