Reputation: 451
So I want to have a constructor for my derived class to which I give an instance of my base class such that my base class is initialized with the input parameter and my derived class follows the default constructor. I came up with this (MWE):
class Derived : public Base {
Derived(){a = 0; b=3;};
Derived(Base * base): Base(*base),Derived(){};
int a;
int b;
}
But this gives me the error error: constructor delegation follows mem-initializer for 'Base'
So how should I do this? I know one way that works but I'm asking if there is a better way such that I don't have the same code in the default constructor and the other constructor.
So I know that this works:
class Derived : public Base {
Derived(){a = 0; b=3;};
Derived(Base * base): Base(*base){a = 0; b=3;};
int a;
int b;
}
Upvotes: 1
Views: 395
Reputation: 4713
The thing is, Derived(...):Derived(){}
; calls default Base
constructor. So adding additional call to constructor of Base
confuses compiler - how should it know what you want?
You can write it as follows if you wish to avoid code duplication:
class Derived : public Base
{
public:
Derived()=default;
Derived(Base * base): Base(*base){};
int a = 0;
int b = 3;
}
Upvotes: 2
Reputation: 41542
One thing that a constructor defines, is how members and bases are initialized. All non-delegating constructors define initializers for all members and bases, either explicitly or implicitly. Your zero-arg Derived
constructor, for instance, default-constructs Base
and a
and b
; in a more idiomatically written version Derived() : a(0), b(3) {}
it would default-construct Base
and initialize a
and b
with 0 and 3 respectively.
So something like Derived(...) : Base(foo), Derived(bar)
is trying to have it both ways. It's trying to use some of the other constructor's initializers, while replacing others. But that's not what delegating constructors were designed to do. A delegating constructor uses and adds to the activity of another constructor; it doesn't modify it.
The general idiom is for constructors to delegate to more explicit constructors. In this case, it sounds like the defaulting of a
and b
to 0 and 3 would ordinarily be done by delegating to a constructor which sets them directly. It depends on what you're trying to accomplish by accepting a pointer to a base class. That's weird and probably not good.
Finally, I should say that while delegated-to constructors aren't open to modification by delegating constructors, default member initializers are open to replacement by explicit initializers. If you just initialize int a=0, b=3
in the class definition, each (non-delegating) constructor can decide whether to let those defaults stand or whether to replace some of them.
Upvotes: 1