own initialization before calling parent's constructor

J

Jeff Flinn

avasilev said:
Hello,
The subject says it - is it legal to initialize fields of the derived
before calling the parent's consctructor, in the initialization list.
For example:

class Base
{
public:
int b;
B(int arg):b(arg){};
};

class Derived: public Base
{
int d;
int calculateValue() {return d+5};
Derived(int arg):
d(arg), B(calculateValue()){};
};

Greetings
Alex

See the boost base from member idiom at:

http://www.boost.org/doc/libs/1_48_0/libs/utility/base_from_member.html

Jeff
 
G

Goran

calculatedValue is an internal stuff that does not concern the outer
world, so passing as constructor argument is out of the question.

Then you can use a static function to create your object and use value
returned from veryLongCalculation there.
And then we are where we started - initializing derived member d,
before calling base constructor :)

Not true. Statement order in initialization list is not execution
order. It can't be. Base classes are construted first irregardless of
this order.

Think about it: if you could do it, then you could construct your own
members before base was constructed. If that could happen, then, upon
an eception in initialization list, destructor wouldn't know what to
do. Imagine:

Derived(params1)
: d(...)
, Base(...)
{
}

Derived(params2)
: Base(...)
, d(...)
{
}

Destruction for exceptions case order would have to be different for
two cases, otherwise an attempt to destroy non-constructed object
could be made.

Goran.
 
S

Stuart Redmann

[snip] I would like to
do some caching of calculated result, which I then use to pass to the
base's constructor, and will use further in the object's lifetime for
other purposes. Normally I would store the result in a variable, and
not initialize any members, but given the limited syntax of
initializer lists, I cannot implement logic that I would do normal
code. Let me clarify with another example:

struct Base
{
Base(int v) {...};

}

struct Derived: public Base
{
int d;
void veryCostlyCalculation()
{
....
d = <calculation result>
}

Derived()
:veryCostlyCalculation(), Base(d) {}

};

In an initialization list, how can I store the result of
veryCostlyCalculation() in a local variable, so that I don't use
members?


This works but isn't pretty:

#include <iostream>

struct Base
{
Base(int v) : dBase(v) { }

int dBase;

};

struct Derived : public Base
{
Derived(int cachedValue = 0) :
Base(cachedValue = veryCostlyCalculation()),
dDerived(cachedValue)
{
}

static int veryCostlyCalculation()
{
std::cout << "veryCostlyCalculation\n";
return 12;
}

int dDerived;

};

int main()
{
Derived d;

std::cout << d.dBase << "\n";
std::cout << d.dDerived << "\n";

}

Not pretty? It's ingenious!

Regards,
Stuart
 
A

avasilev

And then we are where we started - initializing derived member d,
Not true. Statement order in initialization list is not execution
order. It can't be. Base classes are construted first irregardless of
this order.
I agree, was too tired. Your approach of course works, as well as the
others proposed.
Just as a note - my point was not if it is at all possible to do, but
if there is a simple trick to do it, with minimum fuss and changes,
because it is a small optimization that is not worth changing the
design. The thing I didn't know is that the constructor call order is
actually part of the member-init-order-as-declared rule, and base
subobjects are regarded as members in this context.
Thanks to all for the replies
Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top