document number: n2108
Jens Maurer <Jens.Maurer@gmx.net>
Alisdair Meredith <alisdair.meredith@uk.renaultf1.com>
2006-10-13

Explicit Virtual Overides

Problem Description

We would like to tighten the rules for overriding virtual functions, to solve these problems: We are deliberately not solving the problem that a base class B1 has a virtual function f, another base class B2 also has a virtual function f with the same signature, and the user derives a class D from both B1 and B2 and declares D::f to override both B1::f and B2::f, one of which may have been inadvertent.

Proposed Solution

We propose to introduce an "explicit polymorphic class" that requires repeating the "virtual" keyword when overriding virtual functions from base classes and also requires introducing new virtual functions using a special "new virtual" syntax.

We suggest to use the syntax for explicit classes introduced in N1717 "explicit class and default definitions" to mark polymorphic classes as explicitly polymorphic.

Example:

class B {
  virtual void f();
  virtual void h(int);
};

class D explicit : public B {
  virtual void f();          // ok: overrides B::f
  virtual void g(long);      // ill-formed: new virtual function introduced
  new virtual void g2(long); // ok: new virtual function introduced
  void h(int);               // ill-formed: overriding without "virtual"
  virtual void h(long);      // ill-formed: new virtual function introduced
  virtual int h(int);        // ill-formed: return type does not match B::h
};

Rationale

n1827 was presented at the Mont Tremblant meeting as a first pass at this problem. Feedback was positive, but concerned about the 'viral' nature of that proposal, that marked the base class as special, and implied that all descendants must be treated as special as well, even when not marked. This viral problem is resolved by marking the derived class instead.

This paper introduces the concept of an explicit polymorphic class as a refinement of the existing polymorphic class type. The virtual function syntax wording can then be updated to use the new class type, while deferring the final choice of syntax to mark the class as explicit to a later paper. This presentation prefers to re-use the idea of an explicit class presented in n1717, but could easily use the alternative syntax presented by Bjarne (could not find a paper, reference to follow) or some other scheme unique to this proposal if the other papers do not progress.

The scope of the problem was reduced to the minimal necessary to solve the common real-world problems. This means it does not tackle ideas such as 'final overriders' or function renaming, both of which would be available if a scheme closer to the C++/CLI standard was pursued.

Tentative Wording

In 7.1.2p1, add to the syntax of function-specifier the keyword "new".

Change 7.1.2p5 as follows

The virtual and new specifiers shall only be used in declarations of non-static class member functions that appear within a member-specification of a class definition; see 10.3. The new specifier shall only be used in conjunction with the virtual specifier.
Add at the end of 10.3p1
A polymorphic class that is also an explicit class is called an explicit polymorphic class.
Replace in 10.3p2
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), and cv-qualification as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.
by
If a virtual member function vf is declared in a class B and in a class D, derived directly or indirectly from B, a member function vf with the same name is declared, D::vf may override B::vf as follows: If D is not an explicit polymorphic class and the parameter-type-list (8.3.5) and cv-qualification of D::vf are the same as those of B::vf, then D::vf is also virtual (whether or not it is so declared) and it overrides B::vf. If D is an explicit polymorphic class, then D::vf shall be declared virtual and, if the parameter-type-list (8.3.5) and cv-qualification of D::vf are the same as those of B::vf, D::vf overrides B::vf. In an explicit polymorphic class, a virtual member function that does not override one in a base class shall be declared new.