Reputation: 9090
class Base {
public:
Base(int a, int b);
};
class Derived : public Base {
private:
static std::pair<int, int> determine_a_and_b_(int k);
public:
explicit Derived(int k);
};
Derived::Derived(int k) :
// a, b from determine_a_and_b_(k)...
Base(a, b) { }
Is there any way to call determine_a_and_b_
in the constructor of Derived
, to get the values a
and b
, before calling Base::Base
?
It seems that the only way would be to refactor Base
so that it can first be default-constructed into a null object, and then be initialized with a
and b
later, like
Derived::Derived(int k) : Base() {
Base::init_(a, b);
}
Is there any better way to do this, without needing to change Base
?
Edit - made determine_a_and_b_
static
Upvotes: 4
Views: 1598
Reputation: 180630
What you can do here is write a function that returns a Base
and in the function create the base from the std::pair
returned by determine_a_and_b_
. This allows you to conditionally initialize base in the member initialization list. You would have something like
class Base {
public:
Base(int a, int b);
};
class Derived : public Base {
private:
static std::pair<int, int> determine_a_and_b_(int k);
static Base create_base(const std::pair<int, int>& params) { return Base(params.first, params.second); }
public:
explicit Derived(int k);
};
Derived::Derived(int k) : Base(create_base(determine_a_and_b_(k)) {}
Upvotes: 4
Reputation: 11410
Calling member functions before your constructor even starts running is always shady. You end up running code on an object that is not yet constructed.
One alternative is to derive from a second base. That base class is inited first, picks a and b, and you then use those to init your second base class:
class Base {
public:
Base(int a, int b){};
};
class Params
{
protected:
Params()
{
// this replaces std::pair<int, int> determine_a_and_b_(int k);
// put your logic here
_values.first = 0;
_values.second = 1;
}
std::pair<int, int> _values;
};
class Derived : public Params, public Base {
private:
public:
explicit Derived(int k);
};
Derived::Derived(int k) :
Base(_values.first, _values.second)
{
}
Upvotes: 3