CLOS has a neat concept of :before, :after, and :around methods.
- The :before methods are called before the primary method.
- The :after methods are called after the primary method.
- The :around methods are called around the :before+primary+:after sequence.
The :before, :after, and :around methods are chained rather than overridden. Suppose both a parent and child class define a foo method and :before foo method. The child's foo method overrides the parent's foo method, but both the child's and parent's :before foo methods are called before this overridden method is called.
Python decorators provide something similar to the CLOS :around methods. There is nothing like this in C++. It has to be hand-rolled:
class Child : public Parent {
virtual void do_something (Elided arguments) {
do_some_preliminary_stuff();
Parent::do_something (arguments);
do_some_followup_stuff();
}
};
Downsides:
- This is an anti-pattern to some people.
- It requires me to be explicit in specifying the parent class.
- It requires extenders of my classes to follow the same paradigm.
- What if I need to call the grandparent because the parent doesn't override
do_something
, and what about multiple inheritance? - It doesn't quite capture the CLOS concept.
I found these concepts to be quite handy way back when I used Flavors (predecessor to CLOS). I've used the above workaround in a few places, and a few have challenged it as an anti-pattern. (Others have emulated it elsewhere, so the derision is not universal.)
The question: Is this considered an anti-pattern in C++, and are there better workarounds?