[class.derived]

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

## 11.7 Derived classes [class.derived]

### [11.7.1](#general) General [[class.derived.general]](class.derived.general)

[1](#general-1)

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

A list of base classes can be specified in a class definition using
the notation:

[base-clause:](#nt:base-clause "11.7.1 General [class.derived.general]")  
: [*base-specifier-list*](#nt:base-specifier-list "11.7.1 General [class.derived.general]")

[base-specifier-list:](#nt:base-specifier-list "11.7.1 General [class.derived.general]")  
[*base-specifier*](#nt:base-specifier "11.7.1 General [class.derived.general]") ...opt  
[*base-specifier-list*](#nt:base-specifier-list "11.7.1 General [class.derived.general]") , [*base-specifier*](#nt:base-specifier "11.7.1 General [class.derived.general]") ...opt

[base-specifier:](#nt:base-specifier "11.7.1 General [class.derived.general]")  
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*class-or-decltype*](#nt:class-or-decltype "11.7.1 General [class.derived.general]")  
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt virtual [*access-specifier*](#nt:access-specifier "11.7.1 General [class.derived.general]")opt [*class-or-decltype*](#nt:class-or-decltype "11.7.1 General [class.derived.general]")  
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*access-specifier*](#nt:access-specifier "11.7.1 General [class.derived.general]") virtualopt [*class-or-decltype*](#nt:class-or-decltype "11.7.1 General [class.derived.general]")

[class-or-decltype:](#nt:class-or-decltype "11.7.1 General [class.derived.general]")  
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]")  
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") template [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")  
[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]")

[access-specifier:](#nt:access-specifier "11.7.1 General [class.derived.general]")  
private  
protected  
public

The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the [*base-specifier*](#nt:base-specifier "11.7.1 General [class.derived.general]")[.](#general-1.sentence-2)

[2](#general-2)

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

The component names of a [*class-or-decltype*](#nt:class-or-decltype "11.7.1 General [class.derived.general]") are those of its[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"), and/or[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")[.](#general-2.sentence-1)

A [*class-or-decltype*](#nt:class-or-decltype "11.7.1 General [class.derived.general]") shall denote
a (possibly cv-qualified) class type that is not
an incompletely defined class ([[class.mem]](class.mem "11.4 Class members"));
any cv-qualifiers are ignored[.](#general-2.sentence-2)

The class denoted by the [*class-or-decltype*](#nt:class-or-decltype "11.7.1 General [class.derived.general]") of
a [*base-specifier*](#nt:base-specifier "11.7.1 General [class.derived.general]") is called a[*direct base class*](#def:base_class,direct "11.7.1 General [class.derived.general]") for the class being defined;
for each such [*base-specifier*](#nt:base-specifier "11.7.1 General [class.derived.general]"),
the corresponding [*direct base class relationship*](#def:relationship,direct_base_class "11.7.1 General [class.derived.general]") is the ordered pair (D, B)
where D is the class being defined andB is the direct base class[.](#general-2.sentence-3)

The lookup for the component name of
the [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") or [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") is type-only ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#general-2.sentence-4)

A class B is a
base class of a class D if it is a direct base class ofD or a direct base class of one of D's base classes[.](#general-2.sentence-5)

A class is an [*indirect base class*](#def:base_class,indirect "11.7.1 General [class.derived.general]") of another if it is a base
class but not a direct base class[.](#general-2.sentence-6)

A class is said to be (directly or
indirectly) [*derived*](#def:derived) from its (direct or indirect) base
classes[.](#general-2.sentence-7)

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

See [[class.access]](class.access "11.8 Member access control") for the meaning of[*access-specifier*](#nt:access-specifier "11.7.1 General [class.derived.general]")[.](#general-2.sentence-8)

â *end note*]

Members of a base class are also members of the derived class[.](#general-2.sentence-9)

[*Note [2](#general-note-2)*:

Constructors of a base class can be explicitly inherited ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"))[.](#general-2.sentence-10)

Base class members can be referred to in
expressions in the same manner as other members of the derived class,
unless their names are hidden or ambiguous ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))[.](#general-2.sentence-11)

The scope resolution operator ​::​ ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3 Qualified names")) can be used
to refer to a direct or indirect base member explicitly,
even if it is hidden in the derived class[.](#general-2.sentence-12)

A derived class can itself serve as a base class subject to access
control; see [[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members")[.](#general-2.sentence-13)

A pointer to a derived class can be
implicitly converted to a pointer to an accessible unambiguous base
class ([[conv.ptr]](conv.ptr "7.3.12 Pointer conversions"))[.](#general-2.sentence-14)

An lvalue of a derived class type can be bound
to a reference to an accessible unambiguous base
class ([[dcl.init.ref]](dcl.init.ref "9.5.4 References"))[.](#general-2.sentence-15)

â *end note*]

[3](#general-3)

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

The [*base-specifier-list*](#nt:base-specifier-list "11.7.1 General [class.derived.general]") specifies the type of the[*base class subobjects*](#def:base_class_subobjects) contained in an
object of the derived class type[.](#general-3.sentence-1)

[*Example [1](#general-example-1)*: struct Base {int a, b, c;};

struct Derived : Base {int b;};

struct Derived2 : Derived {int c;};

Here, an object of class Derived2 will have a subobject of classDerived which in turn will have a subobject of classBase[.](#general-3.sentence-2)

â *end example*]

[4](#general-4)

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

A [*base-specifier*](#nt:base-specifier "11.7.1 General [class.derived.general]") followed by an ellipsis is a pack
expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#general-4.sentence-1)

[5](#general-5)

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

The order in which the base class subobjects are allocated in the most
derived object ([[intro.object]](intro.object "6.8.2 Object model")) is unspecified[.](#general-5.sentence-1)

[*Note [3](#general-note-3)*:

A derived class and its base class subobjects can be represented by a
directed acyclic graph (DAG) where an arrow means âdirectly derived
fromâ (see Figure [3](#fig:class.dag))[.](#general-5.sentence-2)

An arrow need not have a physical representation in memory[.](#general-5.sentence-3)

A DAG of subobjects is often referred to as a âsubobject latticeâ[.](#general-5.sentence-4)

â *end note*]

![SVG Image](data:image/svg+xml;base64, )  
Figure [3](#fig:class.dag) — Directed acyclic graph [[fig:class.dag]](./fig:class.dag)

[6](#general-6)

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

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

Initialization of objects representing base classes can be specified in
constructors; see [[class.base.init]](class.base.init "11.9.3 Initializing bases and members")[.](#general-6.sentence-1)

â *end note*]

[7](#general-7)

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

[*Note [5](#general-note-5)*:

A base class subobject can have a layout different
from the layout of a most derived object of the same type[.](#general-7.sentence-1)

A base class
subobject can have a polymorphic behavior ([[class.cdtor]](class.cdtor "11.9.5 Construction and destruction"))
different from the polymorphic behavior of a most derived object of the
same type[.](#general-7.sentence-2)

A base class subobject can be of zero size;
however, two subobjects that have the same class type and that belong to
the same most derived object cannot be allocated at the same
address ([[intro.object]](intro.object "6.8.2 Object model"))[.](#general-7.sentence-3)

â *end note*]

### [11.7.2](#class.mi) Multiple base classes [[class.mi]](class.mi)

[1](#class.mi-1)

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

A class can be derived from any number of base classes[.](#class.mi-1.sentence-1)

[*Note [1](#class.mi-note-1)*:

The use of more than one direct base class is often called multiple inheritance[.](#class.mi-1.sentence-2)

â *end note*]

[*Example [1](#class.mi-example-1)*: class A { /* ... */ };class B { /* ... */ };class C { /* ... */ };class D : public A, public B, public C { /* ... */ }; â *end example*]

[2](#class.mi-2)

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

[*Note [2](#class.mi-note-2)*:

The order of derivation is not significant except as specified by the
semantics of initialization by constructor ([[class.base.init]](class.base.init "11.9.3 Initializing bases and members")),
cleanup ([[class.dtor]](class.dtor "11.4.7 Destructors")), and storage
layout ([[class.mem]](class.mem "11.4 Class members"), [[class.access.spec]](class.access.spec "11.8.2 Access specifiers"))[.](#class.mi-2.sentence-1)

â *end note*]

[3](#class.mi-3)

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

A class shall not be specified as a direct base class of a derived class
more than once[.](#class.mi-3.sentence-1)

[*Note [3](#class.mi-note-3)*:

A class can be an indirect base class more than once and can be a direct
and an indirect base class[.](#class.mi-3.sentence-2)

There are limited things that can be done
with such a class;
lookup that finds its non-static data members and member functions
in the scope of the derived class will be ambiguous[.](#class.mi-3.sentence-3)

However, the static members, enumerations and types can be
unambiguously referred to[.](#class.mi-3.sentence-4)

â *end note*]

[*Example [2](#class.mi-example-2)*: class X { /* ... */ };class Y : public X, public X { /* ... */ }; // errorclass L { public: int next; /* ... */ };class A : public L { /* ... */ };class B : public L { /* ... */ };class C : public A, public B { void f(); /* ... */ }; // well-formedclass D : public A, public L { void f(); /* ... */ }; // well-formed â *end example*]

[4](#class.mi-4)

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

A base class specifier that does not contain the keywordvirtual specifies a [*non-virtual base class*](#def:base_class,non-virtual "11.7.2 Multiple base classes [class.mi]")[.](#class.mi-4.sentence-1)

A base
class specifier that contains the keyword virtual specifies a[*virtual base class*](#def:base_class,virtual "11.7.2 Multiple base classes [class.mi]")[.](#class.mi-4.sentence-2)

For each distinct occurrence of a
non-virtual base class in the class lattice of the most derived class,
the most derived object ([[intro.object]](intro.object "6.8.2 Object model")) shall contain a
corresponding distinct base class subobject of that type[.](#class.mi-4.sentence-3)

For each
distinct base class that is specified virtual, the most derived object
shall contain a single base class subobject of that type[.](#class.mi-4.sentence-4)

[5](#class.mi-5)

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

[*Note [4](#class.mi-note-4)*:

For an object of class type C, each distinct occurrence of a
(non-virtual) base class L in the class lattice of C corresponds one-to-one with a distinct L subobject within the
object of type C[.](#class.mi-5.sentence-1)

Given the class C defined above, an
object of class C will have two subobjects of class L as
shown in Figure [4](#fig:class.nonvirt)[.](#class.mi-5.sentence-2)

![SVG Image](data:image/svg+xml;base64, )  
Figure [4](#fig:class.nonvirt) — Non-virtual base [[fig:class.nonvirt]](./fig:class.nonvirt)

In such lattices, explicit qualification can be used to specify which
subobject is meant[.](#class.mi-5.sentence-3)

The body of function C​::​f can refer to the
member next of each L subobject:void C::f() { A::next = B::next; } // well-formed

Without the A​::​ or B​::​ qualifiers, the definition ofC​::​f above would be ill-formed because of
ambiguity ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))[.](#class.mi-5.sentence-5)

â *end note*]

[6](#class.mi-6)

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

[*Note [5](#class.mi-note-5)*:

In contrast, consider the case with a virtual base class:class V { /* ... */ };class A : virtual public V { /* ... */ };class B : virtual public V { /* ... */ };class C : public A, public B { /* ... */ };

![SVG Image](data:image/svg+xml;base64, )  
Figure [5](#fig:class.virt) — Virtual base [[fig:class.virt]](./fig:class.virt)

For an object c of class type C, a single subobject of
type V is shared by every base class subobject of c that has avirtual base class of type V[.](#class.mi-6.sentence-1)

Given the class C defined above, an object of class C will have one subobject of
class V, as shown in Figure [5](#fig:class.virt)[.](#class.mi-6.sentence-2)

â *end note*]

[7](#class.mi-7)

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

[*Note [6](#class.mi-note-6)*:

A class can have both virtual and non-virtual base classes of a given
type[.](#class.mi-7.sentence-1)

class B { /* ... */ };class X : virtual public B { /* ... */ };class Y : virtual public B { /* ... */ };class Z : public B { /* ... */ };class AA : public X, public Y, public Z { /* ... */ };

For an object of class AA, all virtual occurrences of
base class B in the class lattice of AA correspond to a
single B subobject within the object of type AA, and
every other occurrence of a (non-virtual) base class B in the
class lattice of AA corresponds one-to-one with a distinctB subobject within the object of type AA[.](#class.mi-7.sentence-2)

Given the
class AA defined above, class AA has two subobjects of
class B: Z's B and the virtual B shared
by X and Y, as shown in Figure [6](#fig:class.virtnonvirt)[.](#class.mi-7.sentence-3)

![SVG Image](data:image/svg+xml;base64, )  
Figure [6](#fig:class.virtnonvirt) — Virtual and non-virtual base [[fig:class.virtnonvirt]](./fig:class.virtnonvirt)

â *end note*]

### [11.7.3](#class.virtual) Virtual functions [[class.virtual]](class.virtual)

[1](#class.virtual-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)[.](#class.virtual-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](#class.virtual-note-1)*:

Virtual functions support dynamic binding and object-oriented
programming[.](#class.virtual-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]")[.](#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](#class.virtual-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[.](#class.virtual-2.sentence-1)

For convenience, we say that any virtual function overrides itself[.](#class.virtual-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[.](#class.virtual-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[.](#class.virtual-2.sentence-4)

[*Example [1](#class.virtual-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](#class.virtual-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](#class.virtual-3)

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

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

â *end note*]

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

[*Example [3](#class.virtual-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](#class.virtual-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[.](#class.virtual-5.sentence-1)

[*Example [4](#class.virtual-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](#class.virtual-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"))[.](#class.virtual-6.sentence-1)

[*Example [5](#class.virtual-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](#class.virtual-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[.](#class.virtual-7.sentence-1)

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

[9](#class.virtual-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[.](#class.virtual-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"))[.](#class.virtual-9.sentence-2)

[*Example [6](#class.virtual-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](#class.virtual-10)

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

[*Note [3](#class.virtual-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"))[.](#class.virtual-10.sentence-1)

â *end note*]

[11](#class.virtual-11)

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

[*Note [4](#class.virtual-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[.](#class.virtual-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[.](#class.virtual-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[.](#class.virtual-11.sentence-3)

â *end note*]

[12](#class.virtual-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"))[.](#class.virtual-12.sentence-1)

[13](#class.virtual-13)

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

[*Example [7](#class.virtual-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[.](#class.virtual-13.sentence-2)

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

â *end example*]

[14](#class.virtual-14)

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

[*Example [8](#class.virtual-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[.](#class.virtual-14.sentence-2)

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

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

â *end example*]

[15](#class.virtual-15)

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

[*Example [9](#class.virtual-example-9)*:

The following example uses the well-formed classes from above[.](#class.virtual-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](#class.virtual-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[.](#class.virtual-16.sentence-1)

[*Example [10](#class.virtual-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[.](#class.virtual-16.sentence-2)

â *end example*]

[17](#class.virtual-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[.](#class.virtual-17.sentence-1)

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

[18](#class.virtual-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[.](#class.virtual-18.sentence-1)

A consteval virtual function shall not be overridden by
a virtual function that is not consteval[.](#class.virtual-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)

### [11.7.4](#class.abstract) Abstract classes [[class.abstract]](class.abstract)

[1](#class.abstract-1)

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

[*Note [1](#class.abstract-note-1)*:

The abstract class mechanism supports the notion of a general concept,
such as a shape, of which only more concrete variants, such ascircle and square, can actually be used[.](#class.abstract-1.sentence-1)

An abstract
class can also be used to define an interface for which derived classes
provide a variety of implementations[.](#class.abstract-1.sentence-2)

â *end note*]

[2](#class.abstract-2)

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

A virtual function is specified as
a [*pure virtual function*](#def:function,virtual,pure "11.7.4 Abstract classes [class.abstract]") by using a[*pure-specifier*](class.mem.general#nt:pure-specifier "11.4.1 General [class.mem.general]") ([[class.mem]](class.mem "11.4 Class members")) in the function declaration
in the class definition[.](#class.abstract-2.sentence-1)

[*Note [2](#class.abstract-note-2)*:

Such a function might be inherited: see below[.](#class.abstract-2.sentence-2)

â *end note*]

A class is an [*abstract class*](#def:class,abstract "11.7.4 Abstract classes [class.abstract]") if it has at least one pure virtual function[.](#class.abstract-2.sentence-3)

[*Note [3](#class.abstract-note-3)*:

An abstract class can be used only as a base class of some other class;
no objects of an abstract class can be created
except as subobjects of a class
derived from it ([[basic.def]](basic.def "6.2 Declarations and definitions"), [[class.mem]](class.mem "11.4 Class members"))[.](#class.abstract-2.sentence-4)

â *end note*]

A pure virtual function need be defined only if called with, or as if
with ([[class.dtor]](class.dtor "11.4.7 Destructors")), the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") syntax ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3 Qualified names"))[.](#class.abstract-2.sentence-5)

[*Example [1](#class.abstract-example-1)*: class point { /* ... */ };class shape { // abstract class point center;public: point where() { return center; }void move(point p) { center=p; draw(); }virtual void rotate(int) = 0; // pure virtualvirtual void draw() = 0; // pure virtual}; â *end example*]

[*Note [4](#class.abstract-note-4)*:

A function declaration cannot provide both a [*pure-specifier*](class.mem.general#nt:pure-specifier "11.4.1 General [class.mem.general]") and a definition[.](#class.abstract-2.sentence-6)

â *end note*]

[*Example [2](#class.abstract-example-2)*: struct C {virtual void f() = 0 { }; // error}; â *end example*]

[3](#class.abstract-3)

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

[*Note [5](#class.abstract-note-5)*:

An abstract class type cannot be used
as a parameter or return type of
a function being defined ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) or called ([[expr.call]](expr.call "7.6.1.3 Function call")),
except as specified in [[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers")[.](#class.abstract-3.sentence-1)

Further, an abstract class type cannot be used as
the type of an explicit type conversion ([[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10 Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast")),
because the resulting prvalue would be of abstract class type ([[basic.lval]](basic.lval "7.2.1 Value category"))[.](#class.abstract-3.sentence-2)

However, pointers and references to abstract class types
can appear in such contexts[.](#class.abstract-3.sentence-3)

â *end note*]

[4](#class.abstract-4)

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

A class is abstract if it has at least one pure virtual
function for which the final overrider is pure virtual[.](#class.abstract-4.sentence-1)

[*Example [3](#class.abstract-example-3)*: class ab_circle : public shape {int radius;public:void rotate(int) { }// ab_circle​::​draw() is a pure virtual};

Since shape​::​draw() is a pure virtual functionab_circle​::​draw() is a pure virtual by default[.](#class.abstract-4.sentence-2)

The alternative
declaration,class circle : public shape {int radius;public:void rotate(int) { }void draw(); // a definition is required somewhere}; would make class circle non-abstract and a definition ofcircle​::​draw() must be provided[.](#class.abstract-4.sentence-3)

â *end example*]

[5](#class.abstract-5)

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

[*Note [6](#class.abstract-note-6)*:

An abstract class can be derived from a class that is not abstract, and
a pure virtual function can override a virtual function which is not
pure[.](#class.abstract-5.sentence-1)

â *end note*]

[6](#class.abstract-6)

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

Member functions can be called from a constructor (or destructor) of an
abstract class;the effect of making a virtual call ([[class.virtual]](#class.virtual "11.7.3 Virtual functions")) to a pure
virtual function directly or indirectly for the object being created (or
destroyed) from such a constructor (or destructor) is undefined[.](#class.abstract-6.sentence-1)
