Enforcing Inheritance Rules

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.

5 comments

  1. 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. 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. 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. 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(); }
    };

  5. @ Mikael
    In your previous code above, you are the defeating the whole point of having a pure virtual function in a class by overloading it.
    I am sure the compiler(s) will give you a compile error for your code.
    Pure virtual function should do absolutely nothing in the base class( that is no code or lines , or no implementation at all )
    when you mention it in a base class.
    Almost as if it acts as an interface, or base pointer for polymorphism purposes.

    http://answers.google.com/answers/threadview?id=379269
    gives good explanation too.
    ( in the case of having a another member function with the same name of a pure virtual member function )