Enforcing Inheritance Rules

September 18th, 2009

While writing C++ sometimes one wishes that one could squeeze a little more out of the type system. In this particular case, Zack Weinberg (layout-refactorer extraordinaire), wanted to make sure that certain methods always get overridden in derived classes. Unfortunately, in that particular design, those methods were not pure-virtual. At this point most C++ hackers would cry a little and move on without any compiler assistance.

Instead of crying, Zack added a NS_MUST_OVERRIDE attribute to methods along with a matching Dehydra script. See the source code and the bug for how simple it can be to extend C++ with a useful new check.

Nothing makes me happier than seeing developers land big code changes and accompany them with compiler checks instead of relying on programming folklore to maintain important invariants.

4 Responses to “Enforcing Inheritance Rules”

  1. Mikael Olenfalk Says:

    Hi,

    Maybe I missed something but why did he not just make the member function pure-virtual? I mean the function is already virtual and because the new attribute requires the class to be modified I do not really see why one could not just add ‘= 0′.

    Of course by making it pure-virtual the base class cannot be instantiated anymore, however instantiating a class with NS_MUST_OVERRIDE cannot (?) be well-defined anyway otherwise the ‘_MUST_’ doesn’t really make any sense.

    Please enlighten me,

    With kind regards,

    Mikael Olenfalk

  2. tglek Says:

    Overriding isn’t only about replacing methods. OO design also involves calling the same method on the superclass to do involve functionality common to all of the method implementations

  3. Mikael Olenfalk Says:

    Wouldn’t this solve the issue just as well?

    class A {
    public:
    virtual void must_implement() = 0;
    };
    void A::must_implement ()
    { do_common_stuff(); }

    class B : public A {
    public:
    virtual void must_implement()
    { A::do_common_stuff(); do_more_stuff(); }
    };

  4. Mikael Olenfalk Says:

    Sorry, I found a typo in my last comment:

    The body for B::must_implement() should of course call A::must_implement() and not A::do_common_stuff():

    class B : public A {
    public:
    virtual void must_implement()
    { A::must_implement(); do_more_stuff(); }
    };

Leave a Reply