Topic: Preventing inheritance of virtual functions' implementations


Author: sdm@cs.brown.edu (Scott Meyers)
Date: 2 Nov 90 04:00:15 GMT
Raw View
Summary:  We need a way to specify that a virtual function's implementation
          should not be inherited.


There are currently three general ways of declaring member functions, with
three corresponding meanings.  For a class C, we can say:

    1.          void C::foo()   { ... }
    2.  virtual void C::foo()   { ... }  // yes, I know "virtual" is
    3.  virtual void C::foo() = 0;       // illegal outside the class decl...

In all three cases, foo is a concept that makes sense for all objects of
type C or any of its subclasses, but there are additional semantics, as
follows:

    1.  foo's implementation makes sense for all objects of type C or any
        of its subclasses.  In essense, foo's implementation is an
        assertion about an *invariant* aspect of C's semantics, and
        redefinitions of foo in subclasses are suspect.

    2.  foo's implementation provides reasonable default semantics for C
        objects and specializations of C, but foo's implementation often
        needs to change as C is specialized.

    3.  it is not possible to provide default behavior for foo, but the
        concept applies to all objects of type C, and a definition for foo
        must be provided before a subclass may be instantiated.

I propose that we need a forth form, one that means:

    4.  foo identifies an attribute which MUST differentiate
        specializations of C, hence no definition of foo may be inherited.
        (This is in some sense the diametric opposite of case 1.)

As a contrivied example, consider a function we're never supposed to need,
but that is damned useful nonetheless:

    virtual const char * C::className() const { return "C"; }

Here is a member function that should *always* be redefined in subclasses.
Unfortunately, there is no way to require that it be done.

To get the semantics I propose, we need new syntax, always a bad sign.  For
pure virtual functions, a simple application of the "when in doubt, assign
a new meaning to 'const'" rule seems possible:

    virtual void C::foo() const = const 0;
                                  ^^^^^
        // foo is pure virtual in C, and once defined, it must be
        // defined in all further subclasses.  (The extra const suggests
        // "it's inherited definition is ALWAYS null.")

For non-pure (impure?) virtual functions, I'm not sure what to suggest;
the last thing we need is another keyword.

Has anybody besides me ever wanted to have a way to express a requirement
that a function MUST be redefined in subclasses?

Scott
sdm@cs.brown.edu