[class.virtual]

# 11 Classes [[class]](./#class)

## 11.7 Derived classes [[class.derived]](class.derived#class.virtual)

### 11.7.3 Virtual functions [class.virtual]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3830)

A non-static member function is a [*virtual function*](#def:function,virtual "11.7.3 Virtual functions [class.virtual]") if it is first declared with the keyword virtual or
if it overrides a virtual member function declared in a base class
(see below)[.](#1.sentence-1)[92](#footnote-92 "The use of the virtual specifier in the declaration of an overriding function is valid but redundant (has empty semantics).")

[*Note [1](#note-1)*:

Virtual functions support dynamic binding and object-oriented
programming[.](#1.sentence-2)

â *end note*]

A class with a virtual member function is called a [*polymorphic class*](#def:class,polymorphic "11.7.3 Virtual functions [class.virtual]")[.](#1.sentence-3)[93](#footnote-93 "If all virtual functions are immediate functions, the class is still polymorphic even if its internal representation does not otherwise require any additions for that polymorphic behavior.")

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3853)

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 G corresponds ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")) to a declaration of F,
ignoring trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")*s*,
then G [*overrides*](#def:function,virtual,override "11.7.3 Virtual functions [class.virtual]")[94](#footnote-94 "A function with the same name but a different parameter list ([over]) as a virtual function is not necessarily virtual and does not override. Access control ([class.access]) is not considered in determining overriding.")F[.](#2.sentence-1)

For convenience, we say that any virtual function overrides itself[.](#2.sentence-2)

A virtual member function V of a class object S is a [*final
overrider*](#def:final_overrider "11.7.3 Virtual functions [class.virtual]") unless the most derived class ([[intro.object]](intro.object "6.8.2 Object model")) of which S is a
base class subobject (if any) has another member function that overrides V[.](#2.sentence-3)

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[.](#2.sentence-4)

[*Example [1](#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(); // calls B​::​f, the final overrider c.C::f(); // calls A​::​f because of the using-declaration} â *end example*]

[*Example [2](#example-2)*: struct A { virtual void f(); };struct B : A { };struct C : A { void f(); };struct D : B, C { }; // OK, A​::​f and C​::​f are the final overriders// for the B and C subobjects, respectively â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3906)

[*Note [2](#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[.](#3.sentence-1)

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[.](#3.sentence-2)

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3930)

If a virtual function f in some class B is marked with the[*virt-specifier*](class.mem.general#nt:virt-specifier "11.4.1 General [class.mem.general]") final and in a class D derived from B a function D​::​f overrides B​::​f, the program is ill-formed[.](#4.sentence-1)

[*Example [3](#example-3)*: struct B {virtual void f() const final;};

struct D : B {void f() const; // error: D​::​f attempts to override final B​::​f}; â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3946)

If a virtual function is marked with the [*virt-specifier*](class.mem.general#nt:virt-specifier "11.4.1 General [class.mem.general]") override and
does not override a member function of a base class, the program is ill-formed[.](#5.sentence-1)

[*Example [4](#example-4)*: struct B {virtual void f(int);};

struct D : B {virtual void f(long) override; // error: wrong signature overriding B​::​fvirtual void f(int) override; // OK}; â *end example*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3962)

A virtual function shall not have a trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))[.](#6.sentence-1)

[*Example [5](#example-5)*: template<typename T>struct A {virtual void f() requires true; // error: virtual function cannot be constrained ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations"))}; â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3973)

The [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]"), or lack thereof, of an overriding function
shall be the same as that of the overridden function[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L3977)

The return type of an overriding function shall be either identical to
the return type of the overridden function or [*covariant*](#def:return_type,covariant "11.7.3 Virtual functions [class.virtual]") with
the classes of the functions[.](#8.sentence-1)

If a function D​::​f overrides a
function B​::​f, the return types of the functions are covariant
if they satisfy the following criteria:

- [(8.1)](#8.1)

both are pointers to classes, both are lvalue references to
classes, or both are rvalue references to classes[95](#footnote-95 "Multi-level pointers to classes or references to multi-level pointers to classes are not allowed.")

- [(8.2)](#8.2)

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

- [(8.3)](#8.3)

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[.](#8.sentence-2)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4002)

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]](basic.scope.pdecl "6.4.2 Point of declaration")) of the overriding declaration or shall be the
class type D[.](#9.sentence-1)

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]](expr.call "7.6.1.3 Function call"))[.](#9.sentence-2)

[*Example [6](#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(); // error: B (base class of D) inaccessible};

class A;struct Derived : public Base {void vf1(); // virtual and overrides Base​::​vf1()void vf2(int); // not virtual, hides Base​::​vf2()char vf3(); // error: invalid difference in return type only D* vf4(); // OK, returns pointer to derived class A* vf5(); // error: returns pointer to incomplete classvoid f();};

void g() { Derived d;
 Base* bp = &d; // standard conversion:// Derived* to Base* bp->vf1(); // calls Derived​::​vf1() bp->vf2(); // calls Base​::​vf2() bp->f(); // calls Base​::​f() (not virtual) B* p = bp->vf4(); // calls Derived​::​vf4() and converts the// result to B* Derived* dp = &d;
 D* q = dp->vf4(); // calls Derived​::​vf4() and does not// convert the result to B* dp->vf2(); // error: argument mismatch} â *end example*]

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4054)

[*Note [3](#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]](expr.call "7.6.1.3 Function call"))[.](#10.sentence-1)

â *end note*]

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4063)

[*Note [4](#note-4)*:

The virtual specifier implies membership, so a virtual function
cannot be a non-member ([[dcl.fct.spec]](dcl.fct.spec "9.2.3 Function specifiers")) function[.](#11.sentence-1)

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[.](#11.sentence-2)

A virtual
function declared in one class can be declared a friend ([[class.friend]](class.friend "11.8.4 Friends")) in
another class[.](#11.sentence-3)

â *end note*]

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4073)

A virtual function declared in a class shall be defined, or declared
pure ([[class.abstract]](class.abstract "11.7.4 Abstract classes")) in that class, or both; no diagnostic is
required ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#12.sentence-1)

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4080)

[*Example [7](#example-7)*:

Here are some uses of virtual functions with multiple base classes:struct A {virtual void f();};

struct B1 : A { // note non-virtual derivationvoid f();};

struct B2 : A {void f();};

struct D : B1, B2 { // D has two separate A subobjects};

void foo() { D d;// A* ap = &d; // would be ill-formed: ambiguous B1* b1p = &d;
 A* ap = b1p;
 D* dp = &d;
 ap->f(); // calls D​::​B1​::​f dp->f(); // error: ambiguous}

In class D above there are two occurrences of class A and hence two occurrences of the virtual member function A​::​f[.](#13.sentence-2)

The final overrider of B1​::​A​::​f is B1​::​f and the final
overrider of B2​::​A​::​f is B2​::​f[.](#13.sentence-3)

â *end example*]

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4116)

[*Example [8](#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 { // note virtual derivationvoid f();};

struct VB2 : virtual A {void f();};

struct Error : VB1, VB2 { // error};

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[.](#14.sentence-2)

This example is
therefore ill-formed[.](#14.sentence-3)

Class Okay is well-formed, however,
because Okay​::​f is a final overrider[.](#14.sentence-4)

â *end example*]

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4146)

[*Example [9](#example-9)*:

The following example uses the well-formed classes from above[.](#15.sentence-1)

struct VB1a : virtual A { // does not declare f};

struct Da : VB1a, VB2 {};

void foe() { VB1a* vb1ap = new Da;
 vb1ap->f(); // calls VB2​::​f} â *end example*]

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4163)

Explicit qualification with the scope operator ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3 Qualified names"))
suppresses the virtual call mechanism[.](#16.sentence-1)

[*Example [10](#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​::​f really does callB​::​f and notD​::​f[.](#16.sentence-2)

â *end example*]

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4184)

A deleted function ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions")) shall
not override a function that is not deleted[.](#17.sentence-1)

Likewise,
a function that is not deleted shall not override a
deleted function[.](#17.sentence-2)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4191)

A consteval virtual function shall not override
a virtual function that is not consteval[.](#18.sentence-1)

A consteval virtual function shall not be overridden by
a virtual function that is not consteval[.](#18.sentence-2)

[92)](#footnote-92)[92)](#footnoteref-92)

The use of the virtual specifier in the
declaration of an overriding function is valid but redundant (has empty
semantics)[.](#footnote-92.sentence-1)

[93)](#footnote-93)[93)](#footnoteref-93)

If
all virtual functions are immediate functions,
the class is still polymorphic even if
its internal representation does not otherwise require
any additions for that polymorphic behavior[.](#footnote-93.sentence-1)

[94)](#footnote-94)[94)](#footnoteref-94)

A function
with the same name but a different parameter list ([[over]](over "12 Overloading"))
as a virtual function is not necessarily virtual and
does not override[.](#footnote-94.sentence-1)

Access control ([[class.access]](class.access "11.8 Member access control")) is not considered in
determining overriding[.](#footnote-94.sentence-2)

[95)](#footnote-95)[95)](#footnoteref-95)

Multi-level pointers to classes or references to multi-level pointers to
classes are not allowed[.](#footnote-95.sentence-1)
