I'm inheriting a class and I would like to call one of its constructors. However, I have to process some stuff (that doesn't require anything of the base class) before calling it. Is there any way I can just call it later instead of calling it on the initializer list? I believe this can be done in Java and C# but I'm not sure about C++.
The data that I need to pass on the constructor can't be reassigned later, so I can't just call a default constructor and initialize it later.
Is there any way I can just call it later instead of calling it on the initializer list?
No, you cannot. The base class constructor must be called in the initializer list, and it must be called first.
In fact, if you omit it there, the compiler will just add the call implicitly.
I believe this can be done in Java and C# but I'm not sure about C++.
Neither C# nor Java allow this either.
What you can do, however, is call a method as an argument of the base class constructor call. This is then processed before the constructor:
class Derived {
public:
Derived() : Base(some_function()) { }
private:
static int some_function() { return 42; }
};
As was said by several people answering, you cannot delay the invocation of a base class constructor, but Konrad has given a good answer that might well solve your problem. However, this does have its drawbacks (for example, when you need to initialize several functions with values whose calculations share intermediate results), so just to be complete, here's another way of solving the problem of fixed initialization order, by using it.
Given the fixed order of initialization, if you have control over the derived class (and how else would you come to fiddle with one of its ctors?), you can sneak in a private base so that it is going to be initialized before the other base, which can then be initialized with the private base's already calculated values:
class my_dirty_little_secret {
// friend class the_class;
public:
my_dirty_little_secret(const std::string& str)
{
// however that calculates x, y, and z from str I wouldn't know
}
int x;
std::string y;
float z;
};
class the_class : private my_dirty_little_secret // must be first, see ctor
, public the_other_base_class {
public:
the_class(const std::string str)
: my_dirty_little_secret(str)
, the_other_base_class(x, y, z)
{
}
// ...
};
The my_dirty_little_secret
class is a private base so that users of the_class
cannot use it, all of its stuff is private, too, with explicit friendship granting only the_class
access to it. However, since it's listed first in the base class list, it will reliably be constructed before the_other_base_class
, so whatever it calculates can be used to initialize that.
A nice comment at the base class list hopefully prevents from others breaking things by refactoring.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With