[class.virtual] (original) (raw)
11 Classes [class]
11.7 Derived classes [class.derived]
11.7.3 Virtual functions [class.virtual]
A non-static member function is a virtual functionif it is first declared with the keyword virtual or if it overrides a virtual member function declared in a base class (see below).92
[Note 1:
Virtual functions support dynamic binding and object-oriented programming.
— _end note_]
A class with a virtual member function is called a polymorphic class.93
If a virtual member function F is declared in a class B, and, in a class D derived (directly or indirectly) from B, a declaration of a member function Gcorresponds ([basic.scope.scope]) to a declaration of F, ignoring trailing requires-clauses, then G overrides94 F.
For convenience, we say that any virtual function overrides itself.
A virtual member function V of a class object S is a final overrider unless the most derived class ([intro.object]) of which S is a base class subobject (if any) has another member function that overrides V.
In a derived class, if a virtual member function of a base class subobject has more than one final overrider, the program is ill-formed.
[Example 1: struct A { virtual void f();};struct B : virtual A { virtual void f();};struct C : B , virtual A { using A::f;};void foo() { C c; c.f(); c.C::f(); } — _end example_]
[Example 2: struct A { virtual void f(); };struct B : A { };struct C : A { void f(); };struct D : B, C { }; — _end example_]
[Note 2:
A virtual member function does not have to be visible to be overridden, for example,struct B { virtual void f();};struct D : B { void f(int);};struct D2 : D { void f();};the function f(int) in class D hides the virtual function f() in its base class B; D::f(int) is not a virtual function.
However, f() declared in classD2 has the same name and the same parameter list asB::f(), and therefore is a virtual function that overrides the function B::f() even though B::f() is not visible in class D2.
— _end note_]
If a virtual function f in some class B is marked with thevirt-specifier final and in a class D derived from Ba function D::f overrides B::f, the program is ill-formed.
[Example 3: struct B { virtual void f() const final;};struct D : B { void f() const; }; — _end example_]
If a virtual function is marked with the virt-specifier override and does not override a member function of a base class, the program is ill-formed.
[Example 4: struct B { virtual void f(int);};struct D : B { virtual void f(long) override; virtual void f(int) override; }; — _end example_]
[Example 5: template<typename T> struct A { virtual void f() requires true; }; — _end example_]
The ref-qualifier, or lack thereof, of an overriding function shall be the same as that of the overridden function.
The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions.
If a function D::f overrides a function B::f, the return types of the functions are covariant if they satisfy the following criteria:
- both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes95
- the class in the return type of B::f is the same class as the class in the return type of D::f, or is an unambiguous and accessible direct or indirect base class of the class in the return type of D::f
- both pointers or references have the same cv-qualification and the class type in the return type of D::f has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f.
If the class type in the covariant return type of D::f differs from that ofB::f, the class type in the return type of D::f shall be complete at the locus ([basic.scope.pdecl]) of the overriding declaration or shall be the class type D.
When the overriding function is called as the final overrider of the overridden function, its result is converted to the type returned by the (statically chosen) overridden function ([expr.call]).
[Example 6: class B { };class D : private B { friend class Derived; };struct Base { virtual void vf1();virtual void vf2();virtual void vf3();virtual B* vf4();virtual B* vf5();void f();};struct No_good : public Base { D* vf4(); };class A;struct Derived : public Base { void vf1(); void vf2(int); char vf3(); D* vf4(); A* vf5(); void f();};void g() { Derived d; Base* bp = &d; bp->vf1(); bp->vf2(); bp->f(); B* p = bp->vf4(); Derived* dp = &d; D* q = dp->vf4(); dp->vf2(); } — _end example_]
[Note 3:
The interpretation of the call of a virtual function depends on the type of the object for which it is called (the dynamic type), whereas the interpretation of a call of a non-virtual member function depends only on the type of the pointer or reference denoting that object (the static type) ([expr.call]).
— _end note_]
[Note 4:
The virtual specifier implies membership, so a virtual function cannot be a non-member ([dcl.fct.spec]) function.
Nor can a virtual function be a static member, since a virtual function call relies on a specific object for determining which function to invoke.
A virtual function declared in one class can be declared a friend ([class.friend]) in another class.
— _end note_]
A virtual function declared in a class shall be defined, or declared pure ([class.abstract]) in that class, or both; no diagnostic is required ([basic.def.odr]).
[Example 7:
Here are some uses of virtual functions with multiple base classes:struct A { virtual void f();};struct B1 : A { void f();};struct B2 : A { void f();};struct D : B1, B2 { };void foo() { D d; B1* b1p = &d; A* ap = b1p; D* dp = &d; ap->f(); dp->f(); }
In class D above there are two occurrences of class Aand hence two occurrences of the virtual member function A::f.
The final overrider of B1::A::f is B1::f and the final overrider of B2::A::f is B2::f.
— _end example_]
[Example 8:
The following example shows a function that does not have a unique final overrider:struct A { virtual void f();};struct VB1 : virtual A { void f();};struct VB2 : virtual A { void f();};struct Error : VB1, VB2 { };struct Okay : VB1, VB2 { void f();};
Both VB1::f and VB2::f override A::f but there is no overrider of both of them in class Error.
This example is therefore ill-formed.
Class Okay is well-formed, however, because Okay::f is a final overrider.
— _end example_]
[Example 9:
The following example uses the well-formed classes from above.
struct VB1a : virtual A { };struct Da : VB1a, VB2 { };void foe() { VB1a* vb1ap = new Da; vb1ap->f(); } — _end example_]
Explicit qualification with the scope operator ([expr.prim.id.qual]) suppresses the virtual call mechanism.
[Example 10: class B { public: virtual void f(); };class D : public B { public: void f(); };void D::f() { B::f(); }
Here, the function call inD::freally does callB::fand notD::f.
— _end example_]
A deleted function ([dcl.fct.def]) shall not override a function that is not deleted.
Likewise, a function that is not deleted shall not override a deleted function.
A consteval virtual function shall not override a virtual function that is not consteval.
A consteval virtual function shall not be overridden by a virtual function that is not consteval.