pattern support for traversing inheritance chain

Hi all - I have a case where I have a largeish inheritance hierarchy. I will be calling an initialization function on all objects before using them in some fashion. Basically what I need to happen is when I call init() on a Foo the following would occur: void Foo::init() { super::init(); // now with the knowledge that anything I inherited is set up, I can set myself up... } It is not necessary for every call to implement init, in which case the behavior should be that the call is propagated up the inheritance chain (which it is by default in C++). In order to make this work, I need to write different code for "super" in every class implementation, which is a bit error prone. Even if I don't copy/paste, my brain might be on autopilot and type something further up the inheritance chain than it should be. Alternatively, I could require that each class provides a typedef for super, but I'm still relying on myself to remember to call super's init function. Is there anything in boost that would support this kind of hierarchy traversal (semi-)automatically? If there is not, are there suggestions for ways to implement this in a less error-prone fashion? Thanks, Brian

2012/11/8 Brian Budge
Hi all -
I have a case where I have a largeish inheritance hierarchy. I will be calling an initialization function on all objects before using them in some fashion.
Basically what I need to happen is when I call init() on a Foo the following would occur:
void Foo::init() { super::init(); // now with the knowledge that anything I inherited is set up, I can set myself up... }
It is not necessary for every call to implement init, in which case the behavior should be that the call is propagated up the inheritance chain (which it is by default in C++).
In order to make this work, I need to write different code for "super" in every class implementation, which is a bit error prone. Even if I don't copy/paste, my brain might be on autopilot and type something further up the inheritance chain than it should be. Alternatively, I could require that each class provides a typedef for super, but I'm still relying on myself to remember to call super's init function.
Is there anything in boost that would support this kind of hierarchy traversal (semi-)automatically? If there is not, are there suggestions for ways to implement this in a less error-prone fashion?
Thanks, Brian
I think the constructors in C++ work the way you want init() to work. You probably use two-step initialization, don't you? Can you avoid it? Regards, Kris

Thanks for the remark Kris. I had thought of that, but unfortunately, the two-step approach is necessary since I'm using a handle-to-data approach. The actual pointers (objects) associated with the handles may change, and the (possibly incremental) init needs to be re-run for the object. Brian On Wed, Nov 7, 2012 at 3:17 PM, Krzysztof Czainski <1czajnik@gmail.com>wrote:
2012/11/8 Brian Budge
Hi all -
I have a case where I have a largeish inheritance hierarchy. I will be calling an initialization function on all objects before using them in some fashion.
Basically what I need to happen is when I call init() on a Foo the following would occur:
void Foo::init() { super::init(); // now with the knowledge that anything I inherited is set up, I can set myself up... }
It is not necessary for every call to implement init, in which case the behavior should be that the call is propagated up the inheritance chain (which it is by default in C++).
In order to make this work, I need to write different code for "super" in every class implementation, which is a bit error prone. Even if I don't copy/paste, my brain might be on autopilot and type something further up the inheritance chain than it should be. Alternatively, I could require that each class provides a typedef for super, but I'm still relying on myself to remember to call super's init function.
Is there anything in boost that would support this kind of hierarchy traversal (semi-)automatically? If there is not, are there suggestions for ways to implement this in a less error-prone fashion?
Thanks, Brian
I think the constructors in C++ work the way you want init() to work. You probably use two-step initialization, don't you? Can you avoid it?
Regards, Kris
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi Brian,
On Wed, Nov 7, 2012 at 4:04 PM, Brian Budge
Hi all -
I have a case where I have a largeish inheritance hierarchy. I will be calling an initialization function on all objects before using them in some fashion.
Basically what I need to happen is when I call init() on a Foo the following would occur:
void Foo::init() { super::init(); // now with the knowledge that anything I inherited is set up, I can set myself up... }
When I'm dealing with a situation like you describe (not using constructors), I find that Boost.Signals (or Signals2) do what I'm looking for.
I generally do something like the following:
class B
{
typedef boost::signal

On Wed, Nov 7, 2012 at 3:21 PM, Nathan Crookston wrote: Hi Brian, On Wed, Nov 7, 2012 at 4:04 PM, Brian Budge Hi all - I have a case where I have a largeish inheritance hierarchy. I will be
calling an initialization function on all objects before using them in some
fashion. Basically what I need to happen is when I call init() on a Foo the
following would occur: void Foo::init() {
super::init();
// now with the knowledge that anything I inherited is set up, I can
set myself up...
} When I'm dealing with a situation like you describe (not using
constructors), I find that Boost.Signals (or Signals2) do what I'm looking
for. I generally do something like the following: class B
{
typedef boost::signal void onInit() { onInit_(); }
}; class D : public B
{
D() { connectOnInitListener(bind(&D::onInitImpl, this)); } // Register
our onInit handler.
}; //Repeat for further derivatives. This means I don't need to state whom I inherit from, the order of calling
is determined by the order of construction, and if one method doesn't need
to listen for the onInit signal, everything works as expected. HTH,
Nate Hi Nate -
Yes, this seems quite useful. With signal connect, I guess it's
more-or-less pushing-back on a list of function objects? When the signal
is called, it iterates the list and calls each function object?
Thanks for the suggestion. Seems like a good way to go.
Brian

Hi Brain,
On Wed, Nov 7, 2012 at 4:32 PM, Brian Budge
Yes, this seems quite useful. With signal connect, I guess it's more-or-less pushing-back on a list of function objects? When the signal is called, it iterates the list and calls each function object?
Yes, this is the default behavior. The library is much more sophisticated than just that -- you can play with call order, combining return types and more. I first used it to do pretty much what you described, however -- it's eliminated the class of 'called wrong base function' and 'forgot to call base function/ errors. Nate
participants (3)
-
Brian Budge
-
Krzysztof Czainski
-
Nathan Crookston