[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)*: templatestruct 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)