Limitations of initialization list

Discussion in 'C++' started by Marcin Kalicinski, Aug 31, 2004.

  1. Hi,

    Constructor of derived class needs to do some complex things before it calls
    base class constructor. There is an ugly solution:

    bool ComplexThingToDo()
    {
    // ...
    return false; // dummy
    }

    class Derived: public Base
    {
    bool dummy;
    public:
    Derived(): dummy(ComplexThingToDo()), Base() { }
    };

    But I'm afraid that sequence of initializers in initialization list does not
    enforce the actual sequence of execution. So this ugly solution will not
    work. Is there another way? Perhaps it is an example of bad design, doing
    some complex things before calling base class constructor?

    Best regards,
    Marcin
     
    Marcin Kalicinski, Aug 31, 2004
    #1
    1. Advertising

  2. Marcin Kalicinski wrote:
    > Constructor of derived class needs to do some complex things before it calls
    > base class constructor.


    That is not possible.

    > There is an ugly solution:


    It is not a solution.

    >
    > bool ComplexThingToDo()
    > {
    > // ...
    > return false; // dummy
    > }
    >
    > class Derived: public Base
    > {
    > bool dummy;
    > public:
    > Derived(): dummy(ComplexThingToDo()), Base() { }
    > };
    >
    > But I'm afraid that sequence of initializers in initialization list does not
    > enforce the actual sequence of execution. So this ugly solution will not
    > work. Is there another way?


    Not if you can't change the base class. If you _can_ change the base
    class, give your 'Base' class a dummy argument and do

    Derived() : Base(ComplexThingToDo()) {}

    > Perhaps it is an example of bad design, doing
    > some complex things before calling base class constructor?
    >


    Yes, it is. You're trying to call a member function of an object that
    hasn't been constructed yet.

    Victor
     
    Victor Bazarov, Aug 31, 2004
    #2
    1. Advertising

  3. > Perhaps it is an example of bad design, doing
    > > some complex things before calling base class constructor?
    > >

    >
    > Yes, it is. You're trying to call a member function of an object that
    > hasn't been constructed yet.


    Thanks for your reply. But I'm not calling any member, I'm just calling some
    standalone function ComplexThingToDo(), which is not a member of Base, or
    any other class. For example it might initialize some global I/O system in a
    suitable way for the Base class constructor to use.

    Marcin
     
    Marcin Kalicinski, Aug 31, 2004
    #3
  4. Marcin Kalicinski

    Phlip Guest

    Marcin Kalicinski wrote:

    > Constructor of derived class needs to do some complex things before it

    calls
    > base class constructor. There is an ugly solution:
    >
    > bool ComplexThingToDo()
    > {
    > // ...
    > return false; // dummy
    > }
    >
    > class Derived: public Base
    > {
    > bool dummy;
    > public:
    > Derived(): dummy(ComplexThingToDo()), Base() { }
    > };
    >
    > But I'm afraid that sequence of initializers in initialization list does

    not
    > enforce the actual sequence of execution. So this ugly solution will not
    > work.


    Things (generally) destruct in the reverse order that they construct. Hence
    their construction order is (generally) determined. Hence, a class
    constructs bases, then members, in the order they appear in source. So when
    you write dummy(), Base(), the compiler compiles Base(), dummy().

    > Is there another way? Perhaps it is an example of bad design, doing
    > some complex things before calling base class constructor?


    Uh, yeah. How about the constructors do nothing, then you call an init()
    method that does something?

    --
    Phlip
    http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
     
    Phlip, Aug 31, 2004
    #4
  5. > > Is there another way? Perhaps it is an example of bad design, doing
    > > some complex things before calling base class constructor?

    >
    > Uh, yeah. How about the constructors do nothing, then you call an init()
    > method that does something?


    I thought about it also, but it seems to me like abandonning nice and safe
    element of C++ (the constructor/destructor pair) and going a step backwards
    towards C.

    Best regards,
    Marcin
     
    Marcin Kalicinski, Aug 31, 2004
    #5
  6. "Victor Bazarov" <> wrote in message
    news:Np%Yc.582$09.us.to.verio.net...
    > Marcin Kalicinski wrote:
    > > Constructor of derived class needs to do some complex things before it

    calls
    > > base class constructor.

    >
    > That is not possible.


    . . .

    > Not if you can't change the base class. If you _can_ change the base
    > class, give your 'Base' class a dummy argument and do
    >
    > Derived() : Base(ComplexThingToDo()) {}


    You can actually do it even without changing the Base class
    using the following... well... ugly trick:

    class FixBase
    {
    friend Derived;
    FixBase() { /* do the trick here */ }
    };

    class Derived : public Base , private virtual FixBase
    {
    Derived() : Base() { }
    };

    Then, FixBase::FixBase() will always be called before the
    Base::Base() [of the corresponding Derived instance].

    - Risto -
     
    Risto Lankinen, Aug 31, 2004
    #6
  7. Marcin Kalicinski wrote:

    > Constructor of derived class needs to do some complex things before it
    > calls base class constructor. There is an ugly solution:
    >
    > bool ComplexThingToDo()
    > {
    > // ...
    > return false; // dummy
    > }
    >
    > class Derived: public Base
    > {
    > bool dummy;
    > public:
    > Derived(): dummy(ComplexThingToDo()), Base() { }
    > };
    >
    > But I'm afraid that sequence of initializers in initialization list does
    > not enforce the actual sequence of execution. So this ugly solution will
    > not work. Is there another way? Perhaps it is an example of bad design,
    > doing some complex things before calling base class constructor?


    Add another base class.

    class ComplexThing {
    public:
    ComplexThing () { .... }
    };

    class Derived: public ComplexThing, public Base { ... };

    --
    Salu2
     
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Aug 31, 2004
    #7
  8. Marcin Kalicinski wrote:
    > > Perhaps it is an example of bad design, doing

    >
    >>>some complex things before calling base class constructor?
    >>>

    >>
    >>Yes, it is. You're trying to call a member function of an object that
    >>hasn't been constructed yet.

    >
    >
    > Thanks for your reply. But I'm not calling any member, I'm just calling some
    > standalone function ComplexThingToDo(), which is not a member of Base, or
    > any other class. For example it might initialize some global I/O system in a
    > suitable way for the Base class constructor to use.


    My mistake. The others who replied suggested to add another base class to
    your 'Derived' to specifically initialise something before 'Base', it's
    a better solution than changing 'Base' class (that you can't always do).

    V
     
    Victor Bazarov, Aug 31, 2004
    #8
  9. Marcin Kalicinski

    Chris Theis Guest

    "Marcin Kalicinski" <> schrieb im Newsbeitrag
    news:ch1vd8$fmn$...
    > Hi,
    >
    > Constructor of derived class needs to do some complex things before it

    calls
    > base class constructor. There is an ugly solution:
    >
    > bool ComplexThingToDo()
    > {
    > // ...
    > return false; // dummy
    > }
    >
    > class Derived: public Base
    > {
    > bool dummy;
    > public:
    > Derived(): dummy(ComplexThingToDo()), Base() { }
    > };
    >
    > But I'm afraid that sequence of initializers in initialization list does

    not
    > enforce the actual sequence of execution. So this ugly solution will not
    > work. Is there another way? Perhaps it is an example of bad design, doing
    > some complex things before calling base class constructor?
    >
    > Best regards,
    > Marcin
    >


    Naturally objects are constructed top to bottom in the inheritance tree.
    However, you can enforce a specific order of executed base class ctors by
    using multiple and virtual inheritance (see FAQ 25.14). This is a way to
    solve your problem but still I have the itching feeling that you might have
    a flaw in the design. Why can't the complex things be done by the base class
    ctor? If they cannot but it is a problem if they are not yet done when the
    base class ctor is executed then you might have a dependency of a base class
    to a derived class and this is certainly a flaw. I don't suggest that this
    is the case for you but you might consider rethinking your design.

    Cheers
    Chris
     
    Chris Theis, Aug 31, 2004
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    10
    Views:
    991
  2. Replies:
    6
    Views:
    483
    Ron Natalie
    Dec 11, 2005
  3. toton
    Replies:
    5
    Views:
    950
    Victor Bazarov
    Sep 28, 2006
  4. George2
    Replies:
    1
    Views:
    297
    Barry
    Dec 26, 2007
  5. aaragon
    Replies:
    2
    Views:
    637
    James Kanze
    Nov 2, 2008
Loading...

Share This Page