Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #12165 > unrolled thread
| Started by | avasilev <alxvasilev@gmail.com> |
|---|---|
| First post | 2011-12-08 05:07 -0800 |
| Last post | 2011-12-08 16:42 -0500 |
| Articles | 5 on this page of 25 — 10 participants |
Back to article view | Back to comp.lang.c++
own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-08 05:07 -0800
Re: own initialization before calling parent's constructor Victor Bazarov <v.bazarov@comcast.invalid> - 2011-12-08 09:03 -0500
Re: own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-08 08:12 -0800
Re: own initialization before calling parent's constructor Victor Bazarov <v.bazarov@comcast.invalid> - 2011-12-08 12:04 -0500
Re: own initialization before calling parent's constructor Bart v Ingen Schenau <bart@ingen.ddns.info> - 2011-12-08 16:09 +0100
Re: own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-08 08:10 -0800
Re: own initialization before calling parent's constructor Victor Bazarov <v.bazarov@comcast.invalid> - 2011-12-08 12:05 -0500
Re: own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-08 10:22 -0800
Re: own initialization before calling parent's constructor Victor Bazarov <v.bazarov@comcast.invalid> - 2011-12-08 13:44 -0500
Re: own initialization before calling parent's constructor Gert-Jan de Vos <gert-jan.de.vos@onsneteindhoven.nl> - 2011-12-08 10:51 -0800
Re: own initialization before calling parent's constructor Victor Bazarov <v.bazarov@comcast.invalid> - 2011-12-08 14:04 -0500
Re: own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-08 11:07 -0800
Re: own initialization before calling parent's constructor Stuart Redmann <DerTopper@web.de> - 2011-12-09 05:43 -0800
Re: own initialization before calling parent's constructor Goran <goran.pusic@gmail.com> - 2011-12-08 11:09 -0800
Re: own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-08 11:34 -0800
Re: own initialization before calling parent's constructor Victor Bazarov <v.bazarov@comcast.invalid> - 2011-12-08 15:15 -0500
Re: own initialization before calling parent's constructor Goran <goran.pusic@gmail.com> - 2011-12-09 00:07 -0800
Re: own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-09 05:54 -0800
Re: own initialization before calling parent's constructor Kevin McCarty <kmccarty@gmail.com> - 2011-12-08 09:27 -0800
Re: own initialization before calling parent's constructor avasilev <alxvasilev@gmail.com> - 2011-12-08 10:40 -0800
Re: own initialization before calling parent's constructor Victor Bazarov <v.bazarov@comcast.invalid> - 2011-12-08 13:55 -0500
Re: own initialization before calling parent's constructor Kevin McCarty <kmccarty@gmail.com> - 2011-12-08 12:41 -0800
Re: own initialization before calling parent's constructor jgk@panix.com (Joe keane) - 2011-12-08 21:20 +0000
Re: own initialization before calling parent's constructor Paavo Helde <myfirstname@osa.pri.ee> - 2011-12-08 11:17 -0600
Re: own initialization before calling parent's constructor Jeff Flinn <TriumphSprint2000@hotmail.com> - 2011-12-08 16:42 -0500
Page 2 of 2 — ← Prev page 1 [2]
| From | Victor Bazarov <v.bazarov@comcast.invalid> |
|---|---|
| Date | 2011-12-08 13:55 -0500 |
| Message-ID | <jbr16d$31h$1@dont-email.me> |
| In reply to | #12197 |
On 12/8/2011 1:40 PM, avasilev wrote:
> Hi Kevin,
> Thanks for the detailed response.
>> Then your code is simply not going to work. That's just how the
>> language is. The derived class instance (and any non-static members
>> of it) does not yet exist at the time the base class constructor is
>> invoked
>
> I think that says it all! That was also my doubt, and the reason to
> ask.
>
>> You have a few alternatives for a work around, all of which have their
>> ups and downs:
>>
>> 1) Use a static member function of the derived class for the
>> calculation
>
> This will not do - actually my purpose is to cache the result from the
> calculation for later reuse, but in an initializer list I can't have
> local variables, this is why I wanted to use a member variable for
> this purpose.
>
>
>> 2) Use two-phase initialization for the base object
>> 3) Multiple inheritance: move the calculation logic into another base
>> class, and rely on the fact that base class constructors are called in
>> the order in which they are inherited from.
>
> These will technically do the job, but my optimization is too small to
> resort to complicating the design in such ways. I guess I will just
> leave the optimization for later.
You could also try using the default argument mechanism:
class Derived : public Base
{
...
explicit Derived(int a = costlyCalculation()) : Base(a) {}
};
V
--
I do not respond to top-posted replies, please don't ask
[toc] | [prev] | [next] | [standalone]
| From | Kevin McCarty <kmccarty@gmail.com> |
|---|---|
| Date | 2011-12-08 12:41 -0800 |
| Message-ID | <c6341fc8-fc92-427b-bea6-ee0af78fff48@e9g2000prd.googlegroups.com> |
| In reply to | #12197 |
On Dec 8, 10:40 am, avasilev <alxvasi...@gmail.com> wrote:
> Hi Kevin,
> Thanks for the detailed response.
>
> > Then your code is simply not going to work. That's just how the
> > language is. The derived class instance (and any non-static members
> > of it) does not yet exist at the time the base class constructor is
> > invoked
>
> I think that says it all! That was also my doubt, and the reason to
> ask.
>
> > You have a few alternatives for a work around, all of which have their
> > ups and downs:
>
> > 1) Use a static member function of the derived class for the
> > calculation
>
> This will not do - actually my purpose is to cache the result from the
> calculation for later reuse, but in an initializer list I can't have
> local variables, this is why I wanted to use a member variable for
> this purpose.
It *is* cached and can be re-used later. In the #1 replacement design
I suggested, it is cached into Base::b, which you had as public so it
can be accessed by any member function of Derived (or anything else
for that matter), including within the initialization list of the
Derived constructor:
class Derived: public Base
{
int d, cachedResult;
static int calculateValueFrom(int arg) { return arg+5; }
public:
int calculateValue() { return calculateValueFrom(d); }
Derived(int arg):
Base(calculateValueFrom(arg)),
d(arg),
cachedResult(Base::b) { }
};
If Base::b is actually private and for some reason you can't modify
the definition of Base to add an accessor for b, then you can
interpose another class Intermediate between Base and Derived in the
inheritance hierarchy, pass the result of (static)
Derived::calculateValueFrom(int) into the Intermediate constructor,
which stores it there, and have that constructor pass its argument
along into the Base constructor. Then Derived can access the cached
value from Intermediate (this is less than ideal as now you have two
copies of the cached value, of course, one in each parent class --
hope they don't get out of sync).
[On refresh, I think this is also what Gert-Jan suggested.]
From your other post:
On Dec 8, 11:34 am, avasilev <alxvasi...@gmail.com> wrote:
> > : d(calculatedValue)
> > , Base(calculatedValue)
> > {
>
> > }
>
> And then we are where we started - initializing derived member d,
> before calling base constructor :)
No. The order in which objects are initialized before the ctor body
is reached is dependent upon the class declaration, and NOT upon the
order in which they are written in the ctor initializer list: that
order is simply ignored. In the code above, Base's ctor will still be
called before Derived::d is initialized.
It is true that g++ -Wall will warn about the order of the initializer
list above not being consistent with the actual order of
initialization. But in this case it does not matter anyway since
there is no longer a dependency of Base on d nor vice versa. It would
be nice if g++ were smart enough not to display that warning unless it
would actually make a difference, but I suppose that's a hard problem
in general due to possible side effects of ctor arguments.
- Kevin B. McCarty
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2011-12-08 21:20 +0000 |
| Message-ID | <jbr9ni$3sb$2@reader1.panix.com> |
| In reply to | #12180 |
In article <cf59fb10-ec26-48a9-b0cb-ecd5e41c4f17@d10g2000vbf.googlegroups.com>, avasilev <alxvasilev@gmail.com> wrote: >In fact, I have a >reverse dependency - the call to the base constructor depends on some >derived-class members being initialized already. There is some case where the default language init just does -not- work for you. Better to make an 'uninit' constructor and do it step-by-step. If you try to use the C++ stuff when it doesn't fit, you're just stabbing yourself. [i don't know it reflects a design flaw, IMHE this problem comes up with classes that otherwise seem to be fine]
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-12-08 11:17 -0600 |
| Message-ID | <Xns9FB5C43B55319myfirstnameosapriee@216.196.109.131> |
| In reply to | #12165 |
avasilev <alxvasilev@gmail.com> wrote in news:ebf5a2e8-c94a-4380-b21f-
045cf5314fa5@j10g2000vbe.googlegroups.com:
> 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()){};
> };
This does not do what you expect as explained by others. What you can do
is something like:
class Derived: public Base
{
public:
int d;
void InitHack(int arg) {d=arg;}
int calculateValue() {return d+5;}
Derived(int arg):
Base((InitHack(arg), calculateValue())), d(arg) {}
};
I suspect this is not legal either, but probably works at least as far d
is a POD. Not recommended!
hth
Paavo
[toc] | [prev] | [next] | [standalone]
| From | Jeff Flinn <TriumphSprint2000@hotmail.com> |
|---|---|
| Date | 2011-12-08 16:42 -0500 |
| Message-ID | <jbrb29$stp$1@dont-email.me> |
| In reply to | #12165 |
avasilev wrote:
> 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
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c++
csiph-web