[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,PHN2ZyB3aWR0aD0iNzlwdCIgaGVpZ2h0PSIxNDBwdCIgdmlld0JveD0iMC4wMCAwLjAwIDc5LjAwIDE0MC4wMCI+CjxnIGNsYXNzPSJncmFwaCI+CmRhZwoKPGcgY2xhc3M9Im5vZGUiPgpCYXNlCkJhc2UKPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpEZXJpdmVkMQpEZXJpdmVkMQo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkRlcml2ZWQxLSZndDtCYXNlCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0zNS41LC03Ni40MUMzNS41LC04My4zIDM1LjUsLTkyLjkgMzUuNSwtMTAxLjQzIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpEZXJpdmVkMgpEZXJpdmVkMgo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkRlcml2ZWQyLSZndDtEZXJpdmVkMQo8cGF0aCBzdHJva2U9ImJsYWNrIiBmaWxsPSJub25lIiBkPSJNMzUuNSwtMjAuNDFDMzUuNSwtMjcuMyAzNS41LC0zNi45IDM1LjUsLTQ1LjQzIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==) 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,PHN2ZyB2aWV3Qm94PSIwLjAwIDAuMDAgMjI0LjAwIDE0MC4wMCIgaGVpZ2h0PSIxNDBwdCIgd2lkdGg9IjIyNHB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4Kbm9udmlydAoKPGcgY2xhc3M9Im5vZGUiPgpMMQpMCjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KTDIKTAo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+CkEKQQo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkEtJmd0O0wxCjxwYXRoIHN0cm9rZT0iYmxhY2siIGQ9Ik0yNywtNzYuNDFDMjcsLTgzLjMgMjcsLTkyLjkgMjcsLTEwMS40MyIgZmlsbD0ibm9uZSIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQgpCCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQi0mZ3Q7TDIKPHBhdGggZmlsbD0ibm9uZSIgZD0iTTE4OSwtNzYuNDFDMTg5LC04My4zIDE4OSwtOTIuOSAxODksLTEwMS40MyIgc3Ryb2tlPSJibGFjayIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQwpDCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQy0mZ3Q7QQo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNOTQuMjYsLTIwLjE2QzgxLjg1LC0yOC40MyA2My4zNywtNDAuNzUgNDguOTIsLTUwLjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpDLSZndDtCCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjEuNzQsLTIwLjE2QzEzNC4xNSwtMjguNDMgMTUyLjYzLC00MC43NSAxNjcuMDgsLTUwLjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==) 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,PHN2ZyB2aWV3Qm94PSIwLjAwIDAuMDAgMjI0LjAwIDE0MC4wMCIgaGVpZ2h0PSIxNDBwdCIgd2lkdGg9IjIyNHB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4KdmlydAoKPGcgY2xhc3M9Im5vZGUiPgpWClYKPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpBCkEKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpBLSZndDtWCjxwYXRoIGQ9Ik00MC43NCwtNzYuMTZDNTMuMTUsLTg0LjQzIDcxLjYzLC05Ni43NSA4Ni4wOCwtMTA2LjM4IiBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpCCkIKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpCLSZndDtWCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNzUuMjYsLTc2LjE2QzE2Mi44NSwtODQuNDMgMTQ0LjM3LC05Ni43NSAxMjkuOTIsLTEwNi4zOCIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQwpDCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQy0mZ3Q7QQo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNOTQuMjYsLTIwLjE2QzgxLjg1LC0yOC40MyA2My4zNywtNDAuNzUgNDguOTIsLTUwLjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpDLSZndDtCCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjEuNzQsLTIwLjE2QzEzNC4xNSwtMjguNDMgMTUyLjYzLC00MC43NSAxNjcuMDgsLTUwLjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==) 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,PHN2ZyB2aWV3Qm94PSIwLjAwIDAuMDAgMzg2LjAwIDE0MC4wMCIgaGVpZ2h0PSIxNDBwdCIgd2lkdGg9IjM4NnB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4KdmlydG5vbnZpcnQKCjxnIGNsYXNzPSJub2RlIj4KQjEKQgo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+CkIyCkIKPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpBQQpBQQo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+ClgKWAo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkFBLSZndDtYCjxwYXRoIHN0cm9rZT0iYmxhY2siIGZpbGw9Im5vbmUiIGQ9Ik05NC4yNiwtMjAuMTZDODEuODUsLTI4LjQzIDYzLjM3LC00MC43NSA0OC45MiwtNTAuMzgiIC8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiAvPgo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+ClkKWQo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkFBLSZndDtZCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjEuNzQsLTIwLjE2QzEzNC4xNSwtMjguNDMgMTUyLjYzLC00MC43NSAxNjcuMDgsLTUwLjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpaCloKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpBQS0mZ3Q7Wgo8cGF0aCBkPSJNMTM1LjQsLTE3LjA5QzE3OS4wOSwtMjYuOCAyNjQuNiwtNDUuOCAzMTMuNzgsLTU2LjczIiBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpYLSZndDtCMQo8cGF0aCBkPSJNNDAuNzQsLTc2LjE2QzUzLjE1LC04NC40MyA3MS42MywtOTYuNzUgODYuMDgsLTEwNi4zOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KWS0mZ3Q7QjEKPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE3NS4yNiwtNzYuMTZDMTYyLjg1LC04NC40MyAxNDQuMzcsLTk2Ljc1IDEyOS45MiwtMTA2LjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpaLSZndDtCMgo8cGF0aCBkPSJNMzUxLC03Ni40MUMzNTEsLTgzLjMgMzUxLC05Mi45IDM1MSwtMTAxLjQzIiBzdHJva2U9ImJsYWNrIiBmaWxsPSJub25lIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==) 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)*: 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](#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)