M
marcus hall
I am considering a strategy for implementation of a finite state machine.
What I would like to do is to use derived classes to represent the state
of the machine, so the vtable pointer is the state and the virtual methods
are the inputs to the machine.
The heart of the issue is the following construct when changing state:
switch (newstate) {
case MT_IDLE: new(this) MT::IDLE(*this); break;
case MT_WAIT_ACK: new(this) MT::WAIT_ACK(*this); break;
case MT_WAIT_DATA: new(this) MT::WAIT_DATA(*this); break;
}
This is part of a SetState() method of the base class. The base class has
the following:
void *operator new(size_t, MT *mt) { return mt; }
so the placement new "allocates" the same memory that the object currently
occupies. The derived classes include a null copy constructor like:
IDLE(const MT &) {}
So, each line in the switch above just changes the vtable pointer (at least
with g++ with optimization, that is all that is generated).
Does this idea of "polymorphing in place" violate the C++ standard anywhere?
If so, is there any adjustment that could be done to make it compliant?
Is there anything that looks to be problematic with this? Certainly the
derived classes cannot be allowed to increase the memory footprint of the
class, and I should be able to check that statically at compile time in the
new() operator. Anything else that would be recommended?
Thanks in Advance!
Marcus Hall
(e-mail address removed)
What I would like to do is to use derived classes to represent the state
of the machine, so the vtable pointer is the state and the virtual methods
are the inputs to the machine.
The heart of the issue is the following construct when changing state:
switch (newstate) {
case MT_IDLE: new(this) MT::IDLE(*this); break;
case MT_WAIT_ACK: new(this) MT::WAIT_ACK(*this); break;
case MT_WAIT_DATA: new(this) MT::WAIT_DATA(*this); break;
}
This is part of a SetState() method of the base class. The base class has
the following:
void *operator new(size_t, MT *mt) { return mt; }
so the placement new "allocates" the same memory that the object currently
occupies. The derived classes include a null copy constructor like:
IDLE(const MT &) {}
So, each line in the switch above just changes the vtable pointer (at least
with g++ with optimization, that is all that is generated).
Does this idea of "polymorphing in place" violate the C++ standard anywhere?
If so, is there any adjustment that could be done to make it compliant?
Is there anything that looks to be problematic with this? Certainly the
derived classes cannot be allowed to increase the memory footprint of the
class, and I should be able to check that statically at compile time in the
new() operator. Anything else that would be recommended?
Thanks in Advance!
Marcus Hall
(e-mail address removed)