______________________________________________________________________
10 Derived classes [class.derived]
______________________________________________________________________
1 A list of base classes may be specified in a class declaration using
the notation:
base-clause:
: base-specifier-list
base-specifier-list:
base-specifier
base-specifier-list , base-specifier
base-specifier:
::opt nested-name-specifieropt class-name
virtual access-specifieropt ::opt nested-name-specifieropt class-name
access-specifier virtualopt ::opt nested-name-specifieropt class-name
access-specifier:
private
protected
public
The class-name in a base-specifier must denote a previously declared
class (_class_), which is called a direct base class for the class
being declared. 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 an indirect base class of another if it is a base
class but not a direct base class. A class is said to be (directly or
indirectly) derived from its (direct or indirect) base classes. For
the meaning of access-specifier see _class.access_. Unless redefined
in the derived class, members of a base class can be referred to in
expressions as if they were members of the derived class. The base
class members are said to be inherited by the derived class. The
scope resolution operator :: (_expr.prim_) may be used to refer to a
base member explicitly. This allows access to a name that has been
redefined 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 may be implicitly converted to a pointer to
an accessible unambiguous base class (_conv.ptr_). A reference to a
derived class may be implicitly converted to a reference to an acces
sible unambiguous base class (_conv.ref_).
2 For example,
class Base {
public:
int a, b, c;
};
class Derived : public Base {
public:
int b;
};
class Derived2 : public Derived {
public:
int c;
};
3 Here, an object of class Derived2 will have a sub-object of class
Derived which in turn will have a sub-object of class Base. A derived
class and its base class sub-objects can be represented by a directed
acyclic graph (DAG) where an arrow means directly derived from. A DAG
of sub-objects is often referred to as a sub-object lattice. For
example,
Base
|
|
Derived
|
Derived2
Note that the arrows need not have a physical representation in memory
and the order in which the sub-objects appear in memory is unspeci
fied.
4 Initialization of objects representing base classes can be specified
in constructors; see _class.base.init_.
10.1 Multiple base classes [class.mi]
1 A class may be derived from any number of base classes. For example,
class A { /* ... */ };
class B { /* ... */ };
class C { /* ... */ };
class D : public A, public B, public C { /* ... */ };
The use of more than one direct base class is often called multiple
inheritance.
2 The order of derivation is not significant except possibly for default
initialization by constructor (_class.ctor_), for cleanup
(_class.dtor_), and for storage layout (_expr.cast_, _class.mem_,
_class.access.spec_).
3 A class may not be specified as a direct base class of a derived class
more than once but it may be an indirect base class more than once.
class B { /* ... */ };
class D : public B, public B { /* ... */ }; // illegal
class L { /* ... */ };
class A : public L { /* ... */ };
class B : public L { /* ... */ };
class C : public A, public B { /* ... */ }; // legal
Here, an object of class C will have two sub-objects of class L as
shown below.
L L
| |
| |
A B
C
4 The keyword virtual may be added to a base class specifier. A single
sub-object of the virtual base class is shared by every base class
that specified the base class to be virtual. For example,
class V { /* ... */ };
class A : virtual public V { /* ... */ };
class B : virtual public V { /* ... */ };
class C : public A, public B { /* ... */ };
Here class C has only one sub-object of class V, as shown below.
V
A B
C
5 A class may have both virtual and nonvirtual 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 { /* ... */ };
Here class AA has two sub-objects of class B: Z's B and the virtual B
shared by X and Y, as shown below.
B B
|
|
X Y Z
AA
10.2 Member Name Lookup [class.member.lookup]
1 Member name lookup determines the meaning of a name ( id-expression or
qualified-id ) in a class scope. Name lookup can result in an ambigu
ity, in which case the program is ill-formed. For an id-expression,
name lookup begins in the class scope of this; for a qualified-id,
name lookup begins in the scope of the nested-name-specifier. Name
lookup takes place before access control (_class.access_).
2 The following steps define the result of name lookup in a class scope.
First, we consider every declaration for the name in the class and in
each of its base class sub-objects. A member name f in one sub-object
B hides a member name f in a sub-object A if A is a base class sub-
object of B. We eliminate from consideration any declarations that
are so hidden. If the resulting set of declarations are not all from
sub-objects of the same type, or the set has a nonstatic member and
includes declarations from distinct sub-objects, there is an ambiguity
and the program is ill-formed. Otherwise that set is the result of
the lookup.
3 For example,
class A {
public:
int a;
int (*b)();
int f();
int f(int);
int g();
};
class B {
int a;
int b();
public:
int f();
int g;
int h();
int h(int);
};
class C : public A, public B {};
void g(C* pc)
{
pc->a = 1; // error: ambiguous: A::a or B::a
pc->b(); // error: ambiguous: A::b or B::b
pc->f(); // error: ambiguous: A::f or B::f
pc->f(1); // error: ambiguous: A::f or B::f
pc->g(); // error: ambiguous: A::g or B::g
pc->g = 1; // error: ambiguous: A::g or B::g
pc->h(); // ok
pc->h(1); // ok
}
If the name of an overloaded function is unambiguously found overload
ing resolution also takes place before access control. Ambiguities
can often be resolved by qualifying a name with its class name. For
example,
class A {
public:
int f();
};
class B {
public:
int f();
};
class C : public A, public B {
int f() { return A::f() + B::f(); }
};
The definition of ambiguity allows a nonstatic object to be found in
more than one sub-object. When virtual base classes are used, two
base classes can share a common sub-object. For example,
class V { public: int v; };
class A {
public:
int a;
static int s;
enum { e };
};
class B : public A, public virtual V {};
class C : public A, public virtual V {};
class D : public B, public C { };
void f(D* pd)
{
pd->v++; // ok: only one `v' (virtual)
pd->s++; // ok: only one `s' (static)
int i = pd->e; // ok: only one `e' (enumerator)
pd->a++; // error, ambiguous: two `a's in `D'
}
When virtual base classes are used, a hidden declaration may be
reached along a path through the sub-object lattice that does not pass
through the hiding declaration. This is not an ambiguity. The iden
tical use with nonvirtual base classes is an ambiguity; in that case
there is no unique instance of the name that hides all the others.
For example,
class V { public: int f(); int x; };
class W { public: int g(); int y; };
class B : public virtual V, public W
{
public:
int f(); int x;
int g(); int y;
};
class C : public virtual V, public W { };
class D : public B, public C { void g(); };
W V W
B C
D
The names defined in V and the left hand instance of W are hidden by
those in B, but the names defined in the right hand instance of W are
not hidden at all.
void D::g()
{
x++; // ok: B::x hides V::x
f(); // ok: B::f() hides V::f()
y++; // error: B::y and C's W::y
g(); // error: B::g() and C's W::g()
}
An explicit or implicit conversion from a pointer to or an lvalue of a
derived class to a pointer or reference to one of its base classes
must unambiguously refer to a unique object representing the base
class. For example,
class V { };
class A { };
class B : public A, public virtual V { };
class C : public A, public virtual V { };
class D : public B, public C { };
void g()
{
D d;
B* pb = &d;
A* pa = &d; // error, ambiguous: C's A or B's A ?
V* pv = &d; // fine: only one V sub-object
}
10.3 Virtual functions [class.virtual]
1 Virtual functions support dynamic binding and object-oriented program
ming. A class that declares or inherits a virtual function is called
a polymorphic class.
2 If a virtual member function vf is declared in a class Base and in a
class Derived, derived directly or indirectly from Base, a member
function vf with the same name and same parameter list as Base::vf is
declared, then Derived::vf is also virtual (whether or not it is so
declared) and it overrides1) Base::vf. For convenience we say that
any virtual function overrides itself. Then in any well-formed class,
for each virtual function declared in that class or any of its direct
or indirect base classes there is a unique final overrider that over
rides that function and every other overrider of that function.
3 A program is ill-formed if the return type of any overriding function
differs from the return type of the overridden function unless the
return type of the latter is pointer or reference (possibly cv-
qualified) to a class B, and the return type of the former is pointer
or reference (respectively) to a class D such that B is an unambiguous
direct or indirect base class of D, accessible in the class of the
overriding function, and the cv-qualification in the return type of
the overriding function is less than or equal to the cv-qualification
in the return type of the overridden function. In that case when the
overriding function is called as the final overrider of the overridden
function, its result is converted to the type returned by the (stati
cally chosen) overridden function. See _expr.call_. For example,
_________________________
1) A function with the same name but a different parameter list (see
_over_) as a virtual function is not necessarily virtual and does not
override. The use of the virtual specifier in the declaration of an
overriding function is legal but redundant (has empty semantics). Ac
cess control (_class.access_) is not considered in determining over
riding.
class B {};
class D : private B { friend class Derived; };
struct Base {
virtual void vf1();
virtual void vf2();
virtual void vf3();
virtual B* vf4();
void f();
};
struct No_good : public Base {
D* vf4(); // error: B (base class of D) inaccessible
};
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(); // okay: returns pointer to derived class
void 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::pf() and converts the
// result to B*
Derived* dp = &d;
D* q = dp->vf4(); // calls Derived::pf() and does not
// convert the result to B*
dp->vf2(); // ill-formed: argument mismatch
}
4 That is, 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 nonvirtual member function
depends only on the type of the pointer or refe rence denoting that
object (the static type). See _expr.call_.
5 The virtual specifier implies membership, so a virtual function cannot
be a global (nonmember) (_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 can be declared a friend in another class. A virtual func
tion declared in a class must be defined or declared pure
(_class.abstract_) in that class.
6 Following are some examples of virtual functions used with multiple
base classes:
struct A {
virtual void f();
};
struct B1 : A { // note non-virtual derivation
void f();
};
struct B2 : A {
void f();
};
struct D : B1, B2 { // D has two separate A sub-objects
};
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(); // ill-formed: ambiguous
}
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.
7 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 derivation
void f();
};
struct VB2 : virtual A {
void f();
};
struct Error : VB1, VB2 { // ill-formed
};
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.
8 The following example uses the well-formed classes from above.
struct VB1a : virtual A { // does not declare f
};
struct Da : VB1a, VB2 {
};
void foe()
{
VB1a* vb1ap = new Da;
vb1ap->f(); // calls VB2:f
}
9 Explicit qualification with the scope operator (_expr.prim_) sup
presses the virtual call mechanism. For example,
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.
10.4 Abstract classes [class.abstract]
1 The abstract class mechanism supports the notion of a general concept,
such as a shape, of which only more concrete variants, such as circle
and square, can actually be used. An abstract class can also be used
to define an interface for which derived classes provide a variety of
implementations.
2 An abstract class is a class that can be used only as a base class of
some other class; no objects of an abstract class may be created
except as sub-objects of a class derived from it. A class is abstract
if it has at least one pure virtual function (which may be inherited:
see below). A virtual function is specified pure by using a pure-
specifier (_class.mem_) in the function declaration in the class dec
laration. A pure virtual function need be defined only if explicitly
called with the qualified-id syntax (_expr.prim_). For example,
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 virtual
virtual void draw() = 0; // pure virtual
// ...
};
An abstract class may not be used as an parameter type, as a function
return type, or as the type of an explicit conversion. Pointers and
references to an abstract class may be declared. For example,
shape x; // error: object of abstract class
shape* p; // ok
shape f(); // error
void g(shape); // error
shape& h(shape&); // ok
3 Pure virtual functions are inherited as pure virtual functions. For
example,
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 function ab_circle::draw() is a
pure virtual by default. The alternative declaration,
class circle : public shape {
int radius;
public:
void rotate(int) {}
void draw(); // must be defined somewhere
};
would make class circle nonabstract and a definition of circle::draw()
must be provided.
4 An abstract class may be derived from a class that is not abstract,
and a pure virtual function may override a virtual function which is
not pure.
5 Member functions can be called from a constructor of an abstract
class; the effect of calling a pure virtual function directly or indi
rectly for the object being created from such a constructor is unde
fined.
10.5 Summary of scope rules [class.scope]
1 The scope rules for C++ programs can now be summarized. These rules
apply uniformly for all names (including typedef-names (_dcl.typedef_)
and class-names (_class.name_)) wherever the grammar allows such names
in the context discussed by a particular rule. This section discusses
lexical scope only; see _basic.link_ for an explanation of linkage
issues. The notion of point of declaration is discussed in
(_basic.scope_).
2 Any use of a name must be unambiguous (up to overloading) in its scope
(_class.ambig_). Only if the name is found to be unambiguous in its
scope are access rules considered (_class.access_). Only if no access
control errors are found is the type of the object, function, or enu
merator named considered.
3 A name used outside any function and class or prefixed by the unary
scope operator :: (and not qualified by the binary :: operator or the
-> or . operators) must be the name of a global object, function, or
enumerator.
4 A name specified after X::, after obj., where obj is an X or a refer
ence to X, or after ptr->, where ptr is a pointer to X must be the
name of a member of class X or be a member of a base class of X. In
addition, ptr in ptr-> may be an object of a class Y that has opera
tor->() declared so ptr->operator->() eventually resolves to a pointer
to X (_over.ref_).
5 A name that is not qualified in any of the ways described above and
that is used in a function that is not a class member must be declared
before its use in the block in which it occurs or in an enclosing
block or globally. The declaration of a local name hides previous
declarations of the same name in enclosing blocks and at file scope.
In particular, no overloading occurs of names in different scopes
(_over.oper_).
6 A name that is not qualified in any of the ways described above and
that is used in a function that is a nonstatic member of class X must
be declared in the block in which it occurs or in an enclosing block,
be a member of class X or a base class of class X, or be a global
name. The declaration of a local name hides declarations of the same
name in enclosing blocks, members of the function's class, and global
names. The declaration of a member name hides declarations of the
same name in base classes and global names.
7 A name that is not qualified in one of the ways described above and is
used in a static member function of a class X must be declared in the
block in which it occurs, in an enclosing block, be a static member of
class X, or a base class of class X, or be a global name.
8 A function parameter name in a function definition (_dcl.fct.def_) is
in the scope of the outermost block of the function (in particular, it
is a local name). A function parameter name in a function declaration
(_dcl.fct_) that is not a function definition is in a local scope that
disappears immediately after the function declaration. A default
argument is in the scope determined by the point of declaration
(_basic.scope_) of its parameter, but may not access local variables
or nonstatic class members; it is evaluated at each point of call
(_dcl.fct.default_).
9 A ctor-initializer (_class.base.init_) is evaluated in the scope of
the outermost block of the constructor it is specified for. In par
ticular, it can refer to the constructor's parameter names.