|
Boost : |
From: Andreas Huber (ah2003_at_[hidden])
Date: 2004-05-26 16:01:22
Robert Bell wrote:
> Here's one argument in favor of entry()/exit() over
> constructor/destructor. If you use constructors/destructors, your
> hands
> will be tied if someday you want to change your mind about the
> implementation of state entry and exit constructing and destructing
> states (a couple of alternatives have been discussed here, such as
> constructing states when they're entered but not destroying them when
> they're exited). If instead you implement entry and exit with entry()
> and exit() member functions, it doesn't matter if the states are
> constructed and destructed as they are now, constructed at entry point
> and destroyed at machine destruction time, or constructed all at once
> at machine construction time.
>
> I don't have any idea if this flexibility is important or not, but if
> I
> was implementing fsm, I'd consider it.
Believe me, I *am* considering it. I even started dreaming about it :-).
However, no matter from what angle I start to think this through I always
end up with the same bad feeling. If we introduce entry()/exit() for the
reasons you give (more flexibility for optimization?) this essentially means
to tell the users that they must not under any circumstances rely on when
exactly constructors and destructors of state objects are called. Even
worse, they must not even rely on how many times state ctors/dtors are
called. Today they might be called exactly as often as entry()/exit() but
tomorrow they might be called only exactly once. This means that most
non-POD data members of states need to be created on the heap, as you
otherwise wouldn't have a chance to create them inside entry() and destroy
them inside exit(). And believe me, you definitely need to do that when you
design non-trivial FSMs. Therefore, to me entry()/exit() means falling at
least halfway back into medieval times where you always had to explictly
call constructors and destructors yourself (Turbo Pascal).
Please have a look at the StopWatch example and imagine the additional
complexity introduced with entry()/exit() (and ctors/dtors called at
unspecified times). I only want to go there if there are compelling reasons:
- I believe that boost::fsm is already reasonably fast (and there is still
some potential for optimization). Nobody who is actually using it has ever
complained that it is too slow. Someone has even reported that it performs
"very well".
- Nobody has so far presented hard technical facts that support the view
that mapping entry/exit to ctor/dtor is wrong. To the contrary, I think I
have almost proved in my discussion with Dave that exit actions must not
fail and that you *can* recover from failing entry actions.
Regards,
Andreas
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk