Feed on
Posts
Comments

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 Responses to “Enforcing Inheritance Rules”

  1. on 19 Sep 2009 at 1:01 am Mikael Olenfalk

    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. on 19 Sep 2009 at 9:56 am tglek

    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. on 25 Sep 2009 at 4:17 am Mikael Olenfalk

    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. on 25 Sep 2009 at 4:19 am Mikael Olenfalk

    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. on 22 Nov 2009 at 4:57 am Shriram

    @ 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 )

Trackback URI | Comments RSS

Leave a Reply