Reputation: 193
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
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
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