A
class-or-decltype shall denote
a (possibly cv-qualified) class type that is not
an incompletely defined class (
[class.mem]);
any cv-qualifiers are ignored
. A class
B is a
base class of a class
D if it is a direct base class of
D or a direct base class of one of
D's base classes
. A class is said to be (directly or
indirectly)
derived from its (direct or indirect) base
classes
. Members of a base class are also members of the derived class
. [
Note 2:
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])
. The scope resolution operator
:: (
[expr.prim.id.qual]) can be used
to refer to a direct or indirect base member explicitly,
even if it is hidden in the derived class
. A derived class can itself serve as a base class subject to access
control; see
[class.access.base]. A pointer to a derived class can be
implicitly converted to a pointer to an accessible unambiguous base
class (
[conv.ptr])
. An lvalue of a derived class type can be bound
to a reference to an accessible unambiguous base
class (
[dcl.init.ref])
. —
end note]
[
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 class
Derived which in turn will have a subobject of class
Base. —
end example]
The order in which the base class subobjects are allocated in the most
derived object (
[intro.object]) is unspecified
. [
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)
. An arrow need not have a physical representation in memory
. A DAG of subobjects is often referred to as a “subobject lattice”
. —
end note]
[
Note 4:
Initialization of objects representing base classes can be specified in
constructors; see
[class.base.init]. —
end note]
[
Note 5:
A base class subobject can have a layout different
from the layout of a most derived object of the same type
. A base class
subobject can have a polymorphic behavior (
[class.cdtor])
different from the polymorphic behavior of a most derived object of the
same type
. 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])
. —
end note]
A class can be derived from any number of base classes
. [
Note 1:
The use of more than one direct base class is often called multiple inheritance
. —
end note]
[
Example 1:
class A { };
class B { };
class C { };
class D : public A, public B, public C { };
—
end example]
A class shall not be specified as a direct base class of a derived class
more than once
. [
Note 3:
A class can be an indirect base class more than once and can be a direct
and an indirect base class
. 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
. However, the static members, enumerations and types can be
unambiguously referred to
. —
end note]
[
Example 2:
class X { };
class Y : public X, public X { };
class L { public: int next; };
class A : public L { };
class B : public L { };
class C : public A, public B { void f(); };
class D : public A, public L { void f(); };
—
end example]
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]) shall contain a
corresponding distinct base class subobject of that type
. For each
distinct base class that is specified virtual, the most derived object
shall contain a single base class subobject of that type
. [
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. Given the class
C defined above, an
object of class
C will have two subobjects of class
L as
shown in Figure
4.In such lattices, explicit qualification can be used to specify which
subobject is meant
. The body of function C::f can refer to the
member next of each L subobject:
void C::f() { A::next = B::next; }
Without the
A:: or
B:: qualifiers, the definition of
C::f above would be ill-formed because of
ambiguity (
[class.member.lookup])
. —
end note]
[
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 { };
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 a
virtual base class of type V. Given the class
C
defined above, an object of class
C will have one subobject of
class
V, as shown in Figure
5. —
end note]
[
Note 6:
A class can have both virtual and non-virtual base classes of a given
type
. 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 distinct
B subobject within the object of type AA. 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.A non-static member function is a
virtual function
if it is first declared with the keyword
virtual or
if it overrides a virtual member function declared in a base class
(see below). [
Note 1:
Virtual functions support dynamic binding and object-oriented
programming
. —
end note]
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]) to a declaration of
F,
ignoring trailing
requires-clauses,
then
G overrides
F. For convenience, we say that any virtual function overrides itself
. A virtual member function
V of a class object
S is a
final
overrider unless the most derived class (
[intro.object]) of which
S is a
base class subobject (if any) has another member function that overrides
V. In a derived class, if a virtual member function of a base class subobject
has more than one final overrider, the program is ill-formed
. [
Example 1:
struct A {
virtual void f();
};
struct B : virtual A {
virtual void f();
};
struct C : B , virtual A {
using A::f;
};
void foo() {
C c;
c.f();
c.C::f();
}
—
end example]
[
Example 2:
struct A { virtual void f(); };
struct B : A { };
struct C : A { void f(); };
struct D : B, C { };
—
end example]
[
Note 2:
A virtual member function does not have to be visible to be overridden,
for example,
struct B {
virtual void f();
};
struct D : B {
void f(int);
};
struct D2 : D {
void f();
};
the function
f(int) in class
D hides the virtual
function
f() in its base class
B;
D::f(int) is
not a virtual function
. However,
f() declared in class
D2 has the same name and the same parameter list as
B::f(), and therefore is a virtual function that overrides the
function
B::f() even though
B::f() is not visible in
class
D2. —
end note]
If a virtual function
f in some class
B is marked with the
virt-specifier final and in a class D derived from B
a function D::f overrides B::f, the program is ill-formed. [
Example 3:
struct B {
virtual void f() const final;
};
struct D : B {
void f() const;
};
—
end example]
If a virtual function is marked with the
virt-specifier override and
does not override a member function of a base class, the program is ill-formed. [
Example 4:
struct B {
virtual void f(int);
};
struct D : B {
virtual void f(long) override;
virtual void f(int) override;
};
—
end example]
[
Example 5:
template<typename T>
struct A {
virtual void f() requires true;
};
—
end example]
The
ref-qualifier, or lack thereof, of an overriding function
shall be the same as that of the overridden function
.The return type of an overriding function shall be either identical to
the return type of the overridden function or
covariant with
the classes of the functions
. If a function
D::f overrides a
function
B::f, the return types of the functions are covariant
if they satisfy the following criteria:
- both are pointers to classes, both are lvalue references to
classes, or both are rvalue references to classes
- the class in the return type of B::f is the same class as
the class in the return type of D::f, or is an unambiguous and
accessible direct or indirect base class of the class in the return type
of D::f
- both pointers or references have the same cv-qualification and the
class type in the return type of D::f has the same
cv-qualification as or less cv-qualification than the class type in the
return type of B::f.
If the class type in the covariant return type of
D::f differs from that of
B::f, the class type in the return type of
D::f shall be
complete at the locus (
[basic.scope.pdecl]) of the overriding declaration or shall be the
class type
D. When the overriding function is called as the
final overrider of the overridden function, its result is converted to
the type returned by the (statically chosen) overridden
function (
[expr.call])
. [
Example 6:
class B { };
class D : private B { friend class Derived; };
struct Base {
virtual void vf1();
virtual void vf2();
virtual void vf3();
virtual B* vf4();
virtual B* vf5();
void f();
};
struct No_good : public Base {
D* vf4();
};
class A;
struct Derived : public Base {
void vf1();
void vf2(int);
char vf3();
D* vf4();
A* vf5();
void f();
};
void g() {
Derived d;
Base* bp = &d;
bp->vf1();
bp->vf2();
bp->f();
B* p = bp->vf4();
Derived* dp = &d;
D* q = dp->vf4();
dp->vf2();
}
—
end example]
[
Note 3:
The interpretation of the call of a virtual function depends on the type
of the object for which it is called (the dynamic type), whereas the
interpretation of a call of a non-virtual member function depends only
on the type of the pointer or reference denoting that object (the static
type) (
[expr.call])
. —
end note]
[
Note 4:
The
virtual specifier implies membership, so a virtual function
cannot be a non-member ([dcl.fct.spec]) function. Nor can a virtual
function be a static member, since a virtual function call relies on a
specific object for determining which function to invoke
. A virtual
function declared in one class can be declared a friend (
[class.friend]) in
another class
. —
end note]
A virtual function declared in a class shall be defined, or declared
pure (
[class.abstract]) in that class, or both; no diagnostic is
required (
[basic.def.odr])
. [
Example 7:
Here are some uses of virtual functions with multiple base classes:
struct A {
virtual void f();
};
struct B1 : A {
void f();
};
struct B2 : A {
void f();
};
struct D : B1, B2 {
};
void foo() {
D d;
B1* b1p = &d;
A* ap = b1p;
D* dp = &d;
ap->f();
dp->f();
}
In class
D above there are two occurrences of class
A
and hence two occurrences of the virtual member function
A::f. The final overrider of
B1::A::f is
B1::f and the final
overrider of
B2::A::f is
B2::f. —
end example]
[
Example 8:
The following example shows a function that does not have a unique final
overrider:
struct A {
virtual void f();
};
struct VB1 : virtual A {
void f();
};
struct VB2 : virtual A {
void f();
};
struct Error : VB1, VB2 {
};
struct Okay : VB1, VB2 {
void f();
};
Both
VB1::f and
VB2::f override
A::f but there
is no overrider of both of them in class
Error. This example is
therefore ill-formed
. Class
Okay is well-formed, however,
because
Okay::f is a final overrider
. —
end example]
[
Example 9:
The following example uses the well-formed classes from above
. struct VB1a : virtual A {
};
struct Da : VB1a, VB2 {
};
void foe() {
VB1a* vb1ap = new Da;
vb1ap->f();
}
—
end example]
Explicit qualification with the scope operator (
[expr.prim.id.qual])
suppresses the virtual call mechanism
. [
Example 10:
class B { public: virtual void f(); };
class D : public B { public: void f(); };
void D::f() { B::f(); }
Here, the function call in
D::f
really does call
B::f
and not
D::f. —
end example]
A deleted function (
[dcl.fct.def]) shall
not override a function that is not deleted
. Likewise,
a function that is not deleted shall not override a
deleted function
. A class with a
consteval virtual function that overrides
a virtual function that is not consteval
shall have consteval-only type ([basic.types.general]). A
consteval virtual function shall not be overridden by
a virtual function that is not consteval.