Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Limitations of initialization list (http://www.velocityreviews.com/forums/t285327-limitations-of-initialization-list.html)

Marcin Kalicinski 08-31-2004 01:45 PM

Limitations of initialization list
 
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



Victor Bazarov 08-31-2004 01:53 PM

Re: Limitations of initialization list
 
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

Marcin Kalicinski 08-31-2004 02:01 PM

Re: Limitations of initialization list
 
> 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



Phlip 08-31-2004 02:01 PM

Re: Limitations of initialization list
 
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/bi...UserInterfaces



Marcin Kalicinski 08-31-2004 02:05 PM

Re: Limitations of initialization list
 
> > 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



Risto Lankinen 08-31-2004 02:16 PM

Re: Limitations of initialization list
 

"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:Np%Yc.582$Ae.240@newsread1.dllstx09.us.to.ver io.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 -



=?ISO-8859-15?Q?Juli=E1n?= Albo 08-31-2004 02:40 PM

Re: Limitations of initialization list
 
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

Victor Bazarov 08-31-2004 03:01 PM

Re: Limitations of initialization list
 
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

Chris Theis 08-31-2004 03:51 PM

Re: Limitations of initialization list
 

"Marcin Kalicinski" <kalita@poczta.onet.pl> schrieb im Newsbeitrag
news:ch1vd8$fmn$1@korweta.task.gda.pl...
> 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





All times are GMT. The time now is 04:58 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.