Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #12165 > unrolled thread

own initialization before calling parent's constructor

Started byavasilev <alxvasilev@gmail.com>
First post2011-12-08 05:07 -0800
Last post2011-12-08 16:42 -0500
Articles 5 on this page of 25 — 10 participants

Back to article view | Back to comp.lang.c++


Contents

  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]


#12202

FromVictor Bazarov <v.bazarov@comcast.invalid>
Date2011-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]


#12216

FromKevin McCarty <kmccarty@gmail.com>
Date2011-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]


#12221

Fromjgk@panix.com (Joe keane)
Date2011-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]


#12189

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2011-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]


#12222

FromJeff Flinn <TriumphSprint2000@hotmail.com>
Date2011-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