Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 9

 

  Главная      Manuals     Working Draft, Standard for Programming Language C++ (N4713, 2017 year)

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     7      8      9      10     ..

 

 

 

Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 9

 

 

void D::glorp() {
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()
}
— end example ]
11
An explicit or implicit conversion from a pointer to or an expression designating an object of a derived class
to a pointer or reference to one of its base classes shall unambiguously refer to a unique object representing
the base class. [ Example:
struct V { };
struct A { };
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };
void g() {
D d;
B* pb = &d;
A* pa = &d;
// error, ambiguous: C’s A or B’s A?
V* pv = &d;
// OK: only one V subobject
}
— end example ]
12
[ Note: Even if the result of name lookup is unambiguous, use of a name found in multiple subobjects might
still be ambiguous (7.12, 8.5.1.5, 14.2). — end note ]
[ Example:
struct B1 {
void f();
static void f(int);
int i;
};
struct B2 {
void f(double);
};
struct I1: B1 { };
struct I2: B1 { };
struct D: I1, I2, B2 {
using B1::f;
using B2::f;
void g() {
f();
// Ambiguous conversion of this
f(0);
// Unambiguous (static)
f(0.0);
// Unambiguous (only one B2)
int B1::* mpB1 = &D::i;
// Unambiguous
int D::* mpD = &D::i;
// Ambiguous conversion
}
};
— end example ]
13.3
Virtual functions
[class.virtual]
1
[ Note: Virtual functions support dynamic binding and object-oriented programming.
— end note ] 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, parameter-type-list (11.3.5), cv-qualification, and
ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it
is so declared) and it overrides112 Base::vf. For convenience we say that any virtual function overrides itself.
112) A function with the same name but a different parameter list (Clause 16) 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). Access control (Clause 14) is not considered in determining overriding.
§ 13.3
232
A virtual member function C::vf of a class object S is a final overrider unless the most derived class (6.6.2)
of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.
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:
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:
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
[ Note: 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 ]
4
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:
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
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:
struct B {
virtual void f(int);
};
§ 13.3
233
struct D : B {
virtual void f(long) override;
// error: wrong signature overriding B::f
virtual void f(int) override;
// OK
};
— end example ]
6
A virtual function shall not have a trailing requires-clause (Clause 11). [ Example:
struct A {
virtual void f() requires true; // error: virtual function cannot be constrained (17.4.2)
};
— end example ]
7
Even though destructors are not inherited, a destructor in a derived class overrides a base class destructor
declared virtual; see 15.4 and 15.5.
8
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:
(8.1)
both are pointers to classes, both are lvalue references to classes, or both are rvalue references to
classes113
(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)
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.
9
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 point of declaration of D::f 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 (8.5.1.2). [ Example:
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 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()
113) Multi-level pointers to classes or references to multi-level pointers to classes are not allowed.
§ 13.3
234
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();
// ill-formed: argument mismatch
}
— end example ]
10
[Note: 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) (8.5.1.2).
— end note ]
11
[Note: The virtual specifier implies membership, so a virtual function cannot be a non-member (10.1.2)
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 (14.3) in another class.
— end note ]
12
A virtual function declared in a class shall be defined, or declared pure (13.4) in that class, or both; no
diagnostic is required (6.2).
13
[ Example: Here are some uses of virtual functions 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 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();
// 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.
— end
example ]
14
[ Example: 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();
};
§ 13.3
235
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.
— end example ]
15
[ Example: 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
}
— end example ]
16
Explicit qualification with the scope operator (8.4) suppresses the virtual call mechanism. [ 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.
— end example ]
17
A function with a deleted definition (11.4) shall not override a function that does not have a deleted definition.
Likewise, a function that does not have a deleted definition shall not override a function with a deleted
definition.
13.4
Abstract classes
[class.abstract]
1
[Note: 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.
— end note ]
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 can be created except as subobjects of a class derived from it. A class is abstract if it has at least
one pure virtual function. [ Note: Such a function might be inherited: see below.
— end note ] A virtual
function is specified pure by using a pure-specifier (12.2) in the function declaration in the class definition. A
pure virtual function need be defined only if called with, or as if with (15.4), the qualified-id syntax (8.4).
[ 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
};
— end example ] [ Note: A function declaration cannot provide both a pure-specifier and a definition — end
note ]
[ Example:
struct C {
virtual void f() = 0 { };
// ill-formed
};
— end example ]
§ 13.4
236
3
An abstract class shall not be used as a parameter type, as a function return type, or as the type of an
explicit conversion. Pointers and references to an abstract class can be declared. [ Example:
shape x;
// error: object of abstract class
shape* p;
// OK
shape f();
// error
void g(shape);
// error
shape& h(shape&);
// OK
— end example ]
4
A class is abstract if it contains or inherits at least one pure virtual function for which the final overrider is
pure virtual. [ 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();
// a definition is required somewhere
};
would make class circle non-abstract and a definition of circle::draw() must be provided.
— end
example ]
5
[Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may
override a virtual function which is not pure.
— end note ]
6
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a
virtual call (13.3) to a pure virtual function directly or indirectly for the object being created (or destroyed)
from such a constructor (or destructor) is undefined.
§ 13.4
237
14
Member access control
[class.access]
1
A member of a class can be
(1.1)
private; that is, its name can be used only by members and friends of the class in which it is declared.
(1.2)
protected; that is, its name can be used only by members and friends of the class in which it is declared,
by classes derived from that class, and by their friends (see 14.4).
(1.3)
public; that is, its name can be used anywhere without access restriction.
2
A member of a class can also access all the names to which the class has access. A local class of a member
function may access the same names that the member function itself may access.114
3
Members of a class defined with the keyword class are private by default. Members of a class defined with
the keywords struct or union are public by default. [ Example:
class X {
int a;
// X::a is private by default
};
struct S {
int a;
// S::a is public by default
};
— end example ]
4
Access control is applied uniformly to all names, whether the names are referred to from declarations or
expressions.
[Note: Access control applies to names nominated by friend declarations (14.3) and using-
declarations (10.3.3).
— end note ] In the case of overloaded function names, access control is applied to the
function selected by overload resolution. [ Note: Because access control applies to names, if access control is
applied to a typedef name, only the accessibility of the typedef name itself is considered. The accessibility of
the entity referred to by the typedef is not considered. For example,
class A {
class B { };
public:
typedef B BB;
};
void f() {
A::BB x;
// OK, typedef name A::BB is public
A::B y;
// access error, A::B is private
}
— end note ]
5
It should be noted that it is access to members and base classes that is controlled, not their visibility. Names
of members are still visible, and implicit conversions to base classes are still considered, when those members
and base classes are inaccessible. The interpretation of a given construct is established without regard to
access control. If the interpretation established makes use of inaccessible member names or base classes, the
construct is ill-formed.
6
All access controls in Clause 14 affect the ability to access a class member name from the declaration of a
particular entity, including parts of the declaration preceding the name of the entity being declared and, if
the entity is a class, the definitions of members of the class appearing outside the class’s member-specification.
[ Note: This access also applies to implicit references to constructors, conversion functions, and destructors.
— end note ]
7
[ Example:
class A {
typedef int I;
// private member
I f();
114) Access permissions are thus transitive and cumulative to nested and local classes.
Member access control
238
friend I g(I);
static I x;
template<int> struct Q;
template<int> friend struct R;
protected:
struct B { };
};
A::I A::f() { return 0; }
A::I g(A::I p = A::x);
A::I g(A::I p) { return 0; }
A::I A::x = 0;
template<A::I> struct A::Q { };
template<A::I> struct R { };
struct D: A::B, A { };
Here, all the uses of A::I are well-formed because A::f, A::x, and A::Q are members of class A and g and R
are friends of class A. This implies, for example, that access checking on the first use of A::I must be deferred
until it is determined that this use of A::I is as the return type of a member of class A. Similarly, the use of
A::B as a base-specifier is well-formed because D is derived from A, so checking of base-specifier s must be
deferred until the entire base-specifier-list has been seen.
— end example ]
8
The names in a default argument (11.3.6) are bound at the point of declaration, and access is checked at
that point rather than at any points of use of the default argument. Access checking for default arguments in
function templates and in member functions of class templates is performed as described in 17.8.1.
9
The names in a default template-argument (17.1) have their access checked in the context in which they
appear rather than at any points of use of the default template-argument. [ Example:
class B { };
template <class T> class C {
protected:
typedef T TT;
};
template <class U, class V = typename U::TT>
class D : public U { };
D <C<B> >* d;
// access error, C::TT is protected
— end example ]
14.1
Access specifiers
[class.access.spec]
1
Member declarations can be labeled by an access-specifier (Clause 13):
access-specifier : member-specificationopt
An access-specifier specifies the access rules for members following it until the end of the class or until another
access-specifier is encountered. [ Example:
class X {
int a;
// X::a is private by default: class used
public:
int b;
// X::b is public
int c;
// X::c is public
};
— end example ]
2
Any number of access specifiers is allowed and no particular order is required. [ Example:
struct S {
int a;
// S::a is public by default: struct used
protected:
int b;
// S::b is protected
private:
int c;
// S::c is private
§ 14.1
239
public:
int d;
// S::d is public
};
— end example ]
3
[Note: The effect of access control on the order of allocation of data members is described in 12.2. — end
note ]
4
When a member is redeclared within its class definition, the access specified at its redeclaration shall be the
same as at its initial declaration. [ Example:
struct S {
class A;
enum E : int;
private:
class A { };
// error: cannot change access
enum E: int { e0 }; // error: cannot change access
};
— end example ]
5
[Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the
name of the base class in the scope in which it was declared. The injected-class-name might be less accessible
than the name of the base class in the scope in which it was declared.
— end note ]
[ Example:
class A { };
class B : private A { };
class C : public B {
A* p;
// error: injected-class-name A is inaccessible
::A* q;
// OK
};
— end example ]
14.2
Accessibility of base classes and base class members
[class.access.base]
1
If a class is declared to be a base class (Clause 13) for another class using the public access specifier, the
public members of the base class are accessible as public members of the derived class and protected members
of the base class are accessible as protected members of the derived class. If a class is declared to be a
base class for another class using the protected access specifier, the public and protected members of the
base class are accessible as protected members of the derived class. If a class is declared to be a base class
for another class using the private access specifier, the public and protected members of the base class are
accessible as private members of the derived class.115
2
In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with
the class-key struct and private is assumed when the class is defined with the class-key class. [ Example:
class B { /* ... */ };
class D1 : private B { /* ... */ };
class D2 : public B { /* ... */ };
class D3 : B { /* ... */ };
// B private by default
struct D4 : public B { /* ... */ };
struct D5 : private B { /* ... */ };
struct D6 : B { /* ... */ };
// B public by default
class D7 : protected B { /* ... */ };
struct D8 : protected B { /* ... */ };
Here B is a public base of D2, D4, and D6, a private base of D1, D3, and D5, and a protected base of D7 and
D8.
— end example ]
3
[ Note: A member of a private base class might be inaccessible as an inherited member name, but accessible
directly. Because of the rules on pointer conversions (7.11) and explicit casts (8.5.3), a conversion from a
pointer to a derived class to a pointer to an inaccessible base class might be ill-formed if an implicit conversion
is used, but well-formed if an explicit cast is used. For example,
115) As specified previously in Clause 14, private members of a base class remain inaccessible even to derived classes unless
friend declarations within the base class definition are used to grant access explicitly.
§ 14.2
240
class B {
public:
int mi;
// non-static member
static int si;
// static member
};
class D : private B {
};
class DD : public D {
void f();
};
void DD::f() {
mi = 3;
// error: mi is private in D
si = 3;
// error: si is private in D
::B b;
b.mi = 3;
// OK ( b.mi is different from this->mi)
b.si = 3;
// OK ( b.si is different from this->si)
::B::si = 3;
// OK
::B* bp1 = this;
// error: B is a private base class
::B* bp2 = (::B*)this;
// OK with cast
bp2->mi = 3;
// OK: access through a pointer to B.
}
— end note ]
4
A base class B of N is accessible at R, if
(4.1)
an invented public member of B would be a public member of N, or
(4.2)
R occurs in a member or friend of class N, and an invented public member of B would be a private or
protected member of N, or
(4.3)
R occurs in a member or friend of a class P derived from N, and an invented public member of B would
be a private or protected member of P, or
(4.4)
there exists a class S such that B is a base class of S accessible at R and S is a base class of N accessible
at R.
[ Example:
class B {
public:
int m;
};
class S: private B {
friend class N;
};
class N: private S {
void f() {
B* p = this;
// OK because class S satisfies the fourth condition above: B is a base class of N
// accessible in f() because B is an accessible base class of S and S is an accessible
// base class of N.
}
};
— end example ]
5
If a base class is accessible, one can implicitly convert a pointer to a derived class to a pointer to that base
class (7.11, 7.12). [ Note: It follows that members and friends of a class X can implicitly convert an X* to a
pointer to a private or protected immediate base class of X. — end note ] The access to a member is affected
by the class in which the member is named. This naming class is the class in which the member name was
looked up and found. [Note: This class can be explicit, e.g., when a qualified-id is used, or implicit, e.g.,
when a class member access operator (8.5.1.5) is used (including cases where an implicit “this->” is added).
If both a class member access operator and a qualified-id are used to name the member (as in p->T::m), the
class naming the member is the class denoted by the nested-name-specifier of the qualified-id (that is, T).
— end note ] A member m is accessible at the point R when named in class N if
§ 14.2
241
(5.1)
m as a member of N is public, or
(5.2)
m as a member of N is private, and R occurs in a member or friend of class N, or
(5.3)
m as a member of N is protected, and R occurs in a member or friend of class N, or in a member of a
class P derived from N, where m as a member of P is public, private, or protected, or
(5.4)
there exists a base class B of N that is accessible at R, and m is accessible at R when named in class B.
[ Example:
class B;
class A {
private:
int i;
friend void f(B*);
};
class B : public A { };
void f(B* p) {
p->i = 1;
// OK: B* can be implicitly converted to A*, and f has access to i in A
}
— end example ]
6
If a class member access operator, including an implicit “this->”, is used to access a non-static data member
or non-static member function, the reference is ill-formed if the left operand (considered as a pointer in the
.” operator case) cannot be implicitly converted to a pointer to the naming class of the right operand. [ Note:
This requirement is in addition to the requirement that the member be accessible as named.
— end note ]
14.3
Friends
[class.friend]
1
A friend of a class is a function or class that is given permission to use the private and protected member
names from the class. A class specifies its friends, if any, by way of friend declarations. Such declarations give
special access rights to the friends, but they do not make the nominated friends members of the befriending
class. [ Example: The following example illustrates the differences between members and friends:
class X {
int a;
friend void friend_set(X*, int);
public:
void member_set(int);
};
void friend_set(X* p, int i) { p->a = i; }
void X::member_set(int i) { a = i; }
void f() {
X obj;
friend_set(&obj,10);
obj.member_set(10);
}
— end example ]
2
Declaring a class to be a friend implies that the names of private and protected members from the class
granting friendship can be accessed in the base-specifiers and member declarations of the befriended class.
[ Example:
class A {
class B { };
friend class X;
};
struct X : A::B {
// OK: A::B accessible to friend
A::B mx;
// OK: A::B accessible to member of friend
class Y {
A::B my;
// OK: A::B accessible to nested member of friend
};
};
§ 14.3
242
— end example ] [ Example:
class X {
enum { a=100 };
friend class Y;
};
class Y {
int v[X::a];
// OK, Y is a friend of X
};
class Z {
int v[X::a];
// error: X::a is private
};
— end example ]
A class shall not be defined in a friend declaration. [ Example:
class A {
friend class B { };
// error: cannot define class in friend declaration
};
— end example ]
3
A friend declaration that does not declare a function shall have one of the following forms:
friend elaborated-type-specifier ;
friend simple-type-specifier ;
friend typename-specifier ;
[Note: A friend declaration may be the declaration in a template-declaration (Clause 17,
17.6.4). — end
note ] If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class
is declared as a friend; otherwise, the friend declaration is ignored. [ Example:
class C;
typedef C Ct;
class X1 {
friend C;
// OK: class C is a friend
};
class X2 {
friend Ct;
// OK: class C is a friend
friend D;
// error: no type-name D in scope
friend class D;
// OK: elaborated-type-specifier declares new class
};
template <typename T> class R {
friend T;
};
R<C> rc;
// class C is a friend of R<C>
R<int> Ri;
// OK: "friend int;" is ignored
— end example ]
4
A function first declared in a friend declaration has the linkage of the namespace of which it is a member (6.5).
Otherwise, the function retains its previous linkage (10.1.1).
5
When a friend declaration refers to an overloaded name or operator, only the function specified by the
parameter types becomes a friend. A member function of a class X can be a friend of a class Y. [ Example:
class Y {
friend char* X::foo(int);
friend X::X(char);
// constructors can be friends
friend X::~X();
// destructors can be friends
};
— end example ]
§ 14.3
243
6
A function can be defined in a friend declaration of a class if and only if the class is a non-local class (12.4),
the function name is unqualified, and the function has namespace scope. [ Example:
class M {
friend void f() { }
// definition of global f, a friend of M,
// not the definition of a member function
};
— end example ]
7
Such a function is implicitly an inline function (10.1.6). A friend function defined in a class is in the (lexical)
scope of the class in which it is defined. A friend function defined outside the class is not (6.4.1).
8
No storage-class-specifier shall appear in the decl-specifier-seq of a friend declaration.
9
A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend
declaration. The meaning of the friend declaration is the same whether the friend declaration appears in the
private, protected, or public (12.2) portion of the class member-specification.
10
Friendship is neither inherited nor transitive. [ Example:
class A {
friend class B;
int a;
};
class B {
friend class C;
};
class C
{
void f(A* p) {
p->a++;
// error: C is not a friend of A despite being a friend of a friend
}
};
class D : public B
{
void f(A* p) {
p->a++;
// error: D is not a friend of A despite being derived from a friend
}
};
— end example ]
11
If a friend declaration appears in a local class (12.4) and the name specified is an unqualified name, a prior
declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope.
For a friend function declaration, if there is no prior declaration, the program is ill-formed. For a friend class
declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing
non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching
declaration is provided in the innermost enclosing non-class scope. [ Example:
class X;
void a();
void f() {
class Y;
extern void b();
class A {
friend class X;
// OK, but X is a local class, not ::X
friend class Y;
// OK
friend class Z;
// OK, introduces local class Z
friend void a();
// error, ::a is not considered
friend void b();
// OK
friend void c();
// error
};
X* px;
// OK, but ::X is found
Z* pz;
// error, no Z is found
}
— end example ]
§ 14.3
244
14.4
Protected member access
[class.protected]
1
An additional access check beyond those described earlier in Clause 14 is applied when a non-static data
member or non-static member function is a protected member of its naming class (14.2).116 As described
earlier, access to a protected member is granted because the reference occurs in a friend or member of some
class C. If the access is to form a pointer to member (8.5.2.1), the nested-name-specifier shall denote C or a
class derived from C. All other accesses involve a (possibly implicit) object expression (8.5.1.5).
In this case,
the class of the object expression shall be C or a class derived from C. [ Example:
class B {
protected:
int i;
static int j;
};
class D1 : public B {
};
class D2 : public B {
friend void fr(B*,D1*,D2*);
void mem(B*,D1*);
};
void fr(B* pb, D1* p1, D2* p2)
{
pb->i = 1;
// ill-formed
p1->i = 2;
// ill-formed
p2->i = 3;
// OK (access through a D2)
p2->B::i = 4;
// OK (access through a D2, even though naming class is B)
int B::* pmi_B = &B::i;
// ill-formed
int B::* pmi_B2 = &D2::i;
// OK (type of &D2::i is int B::*)
B::j = 5;
// ill-formed (not a friend of naming class B)
D2::j = 6;
// OK (because refers to static member)
}
void D2::mem(B* pb, D1* p1) {
pb->i = 1;
// ill-formed
p1->i = 2;
// ill-formed
i = 3;
// OK (access through this)
B::i = 4;
// OK (access through this, qualification ignored)
int B::* pmi_B = &B::i;
// ill-formed
int B::* pmi_B2 = &D2::i;
// OK
j = 5;
// OK (because j refers to static member)
B::j = 6;
// OK (because B::j refers to static member)
}
void g(B* pb, D1* p1, D2* p2) {
pb->i = 1;
// ill-formed
p1->i = 2;
// ill-formed
p2->i = 3;
// ill-formed
}
— end example ]
14.5
Access to virtual functions
[class.access.virt]
1
The access rules (Clause 14) for a virtual function are determined by its declaration and are not affected by
the rules for a function that later overrides it. [ Example:
class B {
public:
virtual int f();
};
116) This additional check does not apply to other members, e.g., static data members or enumerator member constants.
§ 14.5
245
class D : public B {
private:
int f();
};
void f() {
D d;
B* pb = &d;
D* pd = &d;
pb->f();
// OK: B::f() is public, D::f() is invoked
pd->f();
// error: D::f() is private
}
— end example ]
2
Access is checked at the call point using the type of the expression used to denote the object for which the
member function is called (B* in the example above). The access of the member function in the class in
which it was defined (D in the example above) is in general not known.
14.6
Multiple access
[class.paths]
1
If a name can be reached by several paths through a multiple inheritance graph, the access is that of the
path that gives most access. [ Example:
class W { public: void f(); };
class A : private virtual W { };
class B : public virtual W { };
class C : public A, public B {
void f() { W::f(); }
// OK
};
Since W::f() is available to C::f() along the public path through B, access is allowed.
— end example ]
14.7
Nested classes
[class.access.nest]
1
A nested class is a member and as such has the same access rights as any other member. The members of an
enclosing class have no special access to members of a nested class; the usual access rules (Clause 14) shall
be obeyed. [Example:
class E {
int x;
class B { };
class I {
B b;
// OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i;
// OK: E::I can access E::x
}
};
int g(I* p) {
return p->y;
// error: I::y is private
}
};
— end example ]
§ 14.7
246
15
Special member functions
[special]
1
The default constructor (15.1), copy constructor and copy assignment operator (15.8), move constructor
and move assignment operator (15.8), and destructor (15.4) are special member functions.
[Note: The
implementation will implicitly declare these member functions for some class types when the program does not
explicitly declare them. The implementation will implicitly define them if they are odr-used (6.2) or needed
for constant evaluation (8.6). See 15.1, 15.4 and 15.8.
— end note ] An implicitly-declared special member
function is declared at the closing } of the class-specifier. Programs shall not define implicitly-declared special
member functions.
2
Programs may explicitly refer to implicitly-declared special member functions. [Example: A program may
explicitly call, take the address of, or form a pointer to member to an implicitly-declared special member
function.
struct A { };
// implicitly declared A::operator=
struct B : A {
B& operator=(const B &);
};
B& B::operator=(const B& s) {
this->A::operator=(s);
// well-formed
return *this;
}
— end example ]
3
[Note: The special member functions affect the way objects of class type are created, copied, moved, and
destroyed, and how values can be converted to values of other types. Often such special member functions
are called implicitly.
— end note ]
4
Special member functions obey the usual access rules (Clause 14).
[Example: Declaring a constructor
protected ensures that only derived classes and friends can create objects using it.
— end example ]
5
For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract
(13.4), its virtual base classes are called its potentially constructed subobjects.
15.1
Constructors
[class.ctor]
1
Constructors do not have names. In a declaration of a constructor, the declarator is a function declarator
(11.3.5) of the form
ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional
surrounding parentheses, and the id-expression has one of the following forms:
(1.1)
in a member-declaration that belongs to the member-specification of a class but is not a friend
declaration (14.3), the id-expression is the injected-class-name (Clause 12) of the immediately-enclosing
class;
(1.2)
in a member-declaration that belongs to the member-specification of a class template but is not a friend
declaration, the id-expression is a class-name that names the current instantiation (17.7.2.1) of the
immediately-enclosing class template; or
(1.3)
in a declaration at namespace scope or in a friend declaration, the id-expression is a qualified-id that
names a constructor (6.4.3.1).
The class-name shall not be a typedef-name. In a constructor declaration, each decl-specifier in the optional
decl-specifier-seq shall be friend, inline, explicit, or constexpr. [ Example:
struct S {
S();
// declares the constructor
};
S::S() { }
// defines the constructor
— end example ]
§ 15.1
247
2
A constructor is used to initialize objects of its class type. Because constructors do not have names, they are
never found during name lookup; however an explicit type conversion using the functional notation (8.5.1.3)
will cause a constructor to be called to initialize an object. [ Note: For initialization of objects of class type
see 15.6.
— end note ]
3
A constructor can be invoked for a const, volatile or const volatile object. const and volatile
semantics (10.1.7.1) are not applied on an object under construction. They come into effect when the
constructor for the most derived object (6.6.2) ends.
4
A default constructor for a class X is a constructor of class X for which each parameter that is not a function
parameter pack has a default argument (including the case of a constructor with no parameters). If there is
no user-declared constructor for class X, a non-explicit constructor having no parameters is implicitly declared
as defaulted (11.4). An implicitly-declared default constructor is an inline public member of its class.
5
A defaulted default constructor for class X is defined as deleted if:
(5.1)
X is a union that has a variant member with a non-trivial default constructor and no variant member
of X has a default member initializer,
(5.2)
X is a non-union class that has a variant member M with a non-trivial default constructor and no variant
member of the anonymous union containing M has a default member initializer,
(5.3)
any non-static data member with no default member initializer (12.2) is of reference type,
(5.4)
any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-
equal-initializer does not have a user-provided default constructor,
(5.5)
X is a union and all of its variant members are of const-qualified type (or array thereof),
(5.6)
X is a non-union class and all members of any anonymous union member are of const-qualified type (or
array thereof),
(5.7)
any potentially constructed subobject, except for a non-static data member with a brace-or-equal-
initializer, has class type M (or array thereof) and either M has no default constructor or overload
resolution (16.3) as applied to find M’s corresponding constructor results in an ambiguity or in a function
that is deleted or inaccessible from the defaulted default constructor, or
(5.8)
any potentially constructed subobject has a type with a destructor that is deleted or inaccessible from
the defaulted default constructor.
6
A default constructor is trivial if it is not user-provided and if:
(6.1)
its class has no virtual functions (13.3) and no virtual base classes (13.1), and
(6.2)
no non-static data member of its class has a default member initializer (12.2), and
(6.3)
all the direct base classes of its class have trivial default constructors, and
(6.4)
for all the non-static data members of its class that are of class type (or array thereof), each such class
has a trivial default constructor.
Otherwise, the default constructor is non-trivial.
7
A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2)
to create an object of its class type (6.6.2), when it is needed for constant evaluation (8.6), or when it is
explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set
of initializations of the class that would be performed by a user-written default constructor for that class
with no ctor-initializer (15.6.2) and an empty compound-statement. If that user-written default constructor
would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the
requirements of a constexpr constructor (10.1.5), the implicitly-defined default constructor is constexpr.
Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default
constructors for its base classes and its non-static data members shall have been implicitly defined. [Note:
An implicitly-declared default constructor has an exception specification (18.4). An explicitly-defaulted
definition might have an implicit exception specification, see 11.4.
— end note ]
8
Default constructors are called implicitly to create class objects of static, thread, or automatic storage
duration (6.6.4.1, 6.6.4.2, 6.6.4.3) defined without an initializer (11.6), are called to create class objects of
dynamic storage duration (6.6.4.4) created by a new-expression in which the new-initializer is omitted (8.5.2.4),
or are called when the explicit type conversion syntax (8.5.1.3) is used. A program is ill-formed if the default
constructor for an object is implicitly used and the constructor is not accessible (Clause 14).
§ 15.1
248
9
[Note: 15.6.2 describes the order in which constructors for base classes and non-static data members are
called and describes how arguments can be specified for the calls to these constructors.
— end note ]
10
A return statement in the body of a constructor shall not specify a return value. The address of a constructor
shall not be taken.
11
A functional notation type conversion (8.5.1.3) can be used to create new objects of its type. [Note: The
syntax looks like an explicit call of the constructor.
— end note ] [ Example:
complex zz = complex(1,2.3);
cprint( complex(7.8,1.2) );
— end example ]
12
An object created in this way is unnamed. [Note: 15.2 describes the lifetime of temporary objects.
— end
note ]
[ Note: Explicit constructor calls do not yield lvalues, see 8.2.1.
— end note ]
13
[ Note: Some language constructs have special semantics when used during construction; see 15.6.2 and 15.7.
— end note ]
14
During the construction of an object, if the value of the object or any of its subobjects is accessed through
a glvalue that is not obtained, directly or indirectly, from the constructor’s this pointer, the value of the
object or subobject thus obtained is unspecified. [ Example:
struct C;
void no_opt(C*);
struct C {
int c;
C() : c(0) { no_opt(this); }
};
const C cobj;
void no_opt(C* cptr) {
int i = cobj.c * 100;
// value of cobj.c is unspecified
cptr->c = 1;
cout << cobj.c * 100
// value of cobj.c is unspecified
<< ’\n’;
}
extern struct D d;
struct D {
D(int a) : a(a), b(d.a) {}
int a, b;
};
D d = D(1);
// value of d.b is unspecified
— end example ]
15.2
Temporary objects
[class.temporary]
1
Temporary objects are created
(1.1)
when a prvalue is materialized so that it can be used as a glvalue (7.4),
(1.2)
when needed by the implementation to pass or return an object of trivially-copyable type (see below),
and
(1.3)
when throwing an exception (18.1). [ Note: The lifetime of exception objects is described in 18.1.
— end
note ]
Even when the creation of the temporary object is unevaluated (8.2), all the semantic restrictions shall
be respected as if the temporary object had been created and later destroyed.
[Note: This includes
accessibility (Clause 14) and whether it is deleted, for the constructor selected and for the destructor.
However, in the special case of the operand of a decltype-specifier (8.5.1.2), no temporary is introduced, so
the foregoing does not apply to such a prvalue.
— end note ]
2
The materialization of a temporary object is generally delayed as long as possible in order to avoid creating
unnecessary temporary objects. [ Note: Temporary objects are materialized:
§ 15.2
249
(2.1)
when binding a reference to a prvalue (11.6.3, 8.5.1.3, 8.5.1.7, 8.5.1.9, 8.5.1.11, 8.5.3),
(2.2)
when performing member access on a class prvalue (8.5.1.5, 8.5.4),
(2.3)
when performing an array-to-pointer conversion or subscripting on an array prvalue (7.2, 8.5.1.1),
(2.4)
when initializing an object of type std::initializer_list<T> from a braced-init-list (11.6.4),
(2.5)
for certain unevaluated operands (8.5.1.8, 8.5.2.3), and
(2.6)
when a prvalue appears as a discarded-value expression (8.2).
— end note ] [ Example: Consider the following code:
class X {
public:
X(int);
X(const X&);
X& operator=(const X&);
~X();
};
class Y {
public:
Y(int);
Y(Y&&);
~Y();
};
X f(X);
Y g(Y);
void h() {
X a(1);
X b = f(X(2));
Y c = g(Y(3));
a = f(a);
}
X(2) is constructed in the space used to hold f()’s argument and Y(3) is constructed in the space used
to hold g()’s argument. Likewise, f()’s result is constructed directly in b and g()’s result is constructed
directly in c. On the other hand, the expression a = f(a) requires a temporary for the result of f(a), which
is materialized so that the reference parameter of A::operator=(const A&) can bind to it.
— end example ]
3
When an object of class type X is passed to or returned from a function, if each copy constructor, move
constructor, and destructor of X is either trivial or deleted, and X has at least one non-deleted copy or move
constructor, implementations are permitted to create a temporary object to hold the function parameter or
result object. The temporary object is constructed from the function argument or return value, respectively,
and the function’s parameter or return object is initialized as if by using the non-deleted trivial constructor
to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution
to perform a copy or move of the object). [ Note: This latitude is granted to allow objects of class type to be
passed to or returned from functions in registers.
— end note ]
4
When an implementation introduces a temporary object of a class that has a non-trivial constructor (15.1,
15.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be
called for a temporary with a non-trivial destructor (15.4). Temporary objects are destroyed as the last step in
evaluating the full-expression (6.8.1) that (lexically) contains the point where they were created. This is true
even if that evaluation ends in throwing an exception. The value computations and side effects of destroying
a temporary object are associated only with the full-expression, not with any specific subexpression.
5
There are three contexts in which temporaries are destroyed at a different point than the end of the full-
expression. The first context is when a default constructor is called to initialize an element of an array
with no corresponding initializer (11.6). The second context is when a copy constructor is called to copy an
element of an array while the entire array is copied (8.4.5.2, 15.8). In either case, if the constructor has one
or more default arguments, the destruction of every temporary created in a default argument is sequenced
before the construction of the next array element, if any.
§ 15.2
250
6
The third context is when a reference is bound to a temporary object.117 The temporary object to which the
reference is bound or the temporary object that is the complete object of a subobject to which the reference
is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained
through one of the following:
(6.1)
a temporary materialization conversion (7.4),
(6.2)
( expression ), where expression is one of these expressions,
(6.3)
subscripting (8.5.1.1) of an array operand, where that operand is one of these expressions,
(6.4)
a class member access (8.5.1.5) using the . operator where the left operand is one of these expressions
and the right operand designates a non-static data member of non-reference type,
(6.5)
a pointer-to-member operation (8.5.4) using the .* operator where the left operand is one of these
expressions and the right operand is a pointer to data member of non-reference type,
(6.6)
a
(6.6.1)
const_cast (8.5.1.11),
(6.6.2)
static_cast (8.5.1.9),
(6.6.3)
dynamic_cast (8.5.1.7), or
(6.6.4)
reinterpret_cast (8.5.1.10)
converting, without a user-defined conversion, a glvalue operand that is one of these expressions to a
glvalue that refers to the object designated by the operand, or to its complete object or a subobject
thereof,
(6.7)
a conditional expression (8.5.16) that is a glvalue where the second or third operand is one of these
expressions, or
(6.8)
a comma expression (8.5.19) that is a glvalue where the right operand is one of these expressions.
[ Example:
template<typename T> using id = T;
int&& a = id<int[3]>{1, 2, 3}[i];
// temporary array has same lifetime as a
const int& b = static_cast<const int&>(0); // temporary int has same lifetime as b
int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0);
// exactly one of the two temporaries is lifetime-extended
— end example ] [ Note: An explicit type conversion (8.5.1.3, 8.5.3) is interpreted as a sequence of elementary
casts, covered above. [ Example:
const int& x = (const int&)1;
// temporary for value 1 has same lifetime as x
— end example ]
— end note ] [ Note: If a temporary object has a reference member initialized by another
temporary object, lifetime extension applies recursively to such a member’s initializer. [ Example:
struct S {
const int& m;
};
const S& s = S{1};
// both S and int temporaries have lifetime of s
— end example ]
— end note ]
The exceptions to this lifetime rule are:
(6.9)
A temporary object bound to a reference parameter in a function call (8.5.1.2) persists until the
completion of the full-expression containing the call.
(6.10)
The lifetime of a temporary bound to the returned value in a function return statement (9.6.3) is not
extended; the temporary is destroyed at the end of the full-expression in the return statement.
(6.11)
A temporary bound to a reference in a new-initializer (8.5.2.4) persists until the completion of the
full-expression containing the new-initializer. [ Note: This may introduce a dangling reference.
— end
note ]
[ Example:
struct S { int mi; const std::pair<int,int>& mp; };
S a { 1, {2,3} };
117) The same rules apply to initialization of an initializer_list object (11.6.4) with its underlying temporary array.
§ 15.2
251
S* p = new S{ 1, {2,3} };
// creates dangling reference
— end example ]
7
The destruction of a temporary whose lifetime is not extended by being bound to a reference is sequenced
before the destruction of every temporary which is constructed earlier in the same full-expression. If the
lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries
are destroyed at that point in the reverse order of the completion of their construction. In addition, the
destruction of temporaries bound to references shall take into account the ordering of destruction of objects
with static, thread, or automatic storage duration (6.6.4.1, 6.6.4.2, 6.6.4.3); that is, if obj1 is an object with
the same storage duration as the temporary and created before the temporary is created the temporary shall
be destroyed before obj1 is destroyed; if obj2 is an object with the same storage duration as the temporary
and created after the temporary is created the temporary shall be destroyed after obj2 is destroyed.
8
[ Example:
struct S {
S();
S(int);
friend S operator+(const S&, const S&);
~S();
};
S obj1;
const S& cr = S(16)+S(23);
S obj2;
the expression S(16) + S(23) creates three temporaries: a first temporary T1 to hold the result of the
expression S(16), a second temporary T2 to hold the result of the expression S(23), and a third temporary T3
to hold the result of the addition of these two expressions. The temporary T3 is then bound to the reference
cr. It is unspecified whether T1 or T2 is created first. On an implementation where T1 is created before
T2, T2 shall be destroyed before T1. The temporaries T1 and T2 are bound to the reference parameters of
operator+; these temporaries are destroyed at the end of the full-expression containing the call to operator+.
The temporary T3 bound to the reference cr is destroyed at the end of cr’s lifetime, that is, at the end of the
program. In addition, the order in which T3 is destroyed takes into account the destruction order of other
objects with static storage duration. That is, because obj1 is constructed before T3, and T3 is constructed
before obj2, obj2 shall be destroyed before T3, and T3 shall be destroyed before obj1.
— end example ]
15.3
Conversions
[class.conv]
1
Type conversions of class objects can be specified by constructors and by conversion functions. These
conversions are called user-defined conversions and are used for implicit type conversions (Clause 7), for
initialization (11.6), and for explicit type conversions (8.5.3, 8.5.1.9).
2
User-defined conversions are applied only where they are unambiguous (13.2, 15.3.2). Conversions obey the
access control rules (Clause 14). Access control is applied after ambiguity resolution (6.4).
3
[ Note: See 16.3 for a discussion of the use of conversions in function calls as well as examples below.
— end
note ]
4
At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single
value. [ Example:
struct X {
operator int();
};
struct Y {
operator X();
};
Y a;
int b = a;
// error, a.operator X().operator int() not tried
int c = X(a);
// OK: a.operator X().operator int()
— end example ]
5
User-defined conversions are used implicitly only if they are unambiguous. A conversion function in a
derived class does not hide a conversion function in a base class unless the two functions convert to the same
§ 15.3
252
type. Function overload resolution (16.3.3) selects the best conversion function to perform the conversion.
[ Example:
struct X {
operator int();
};
struct Y : X {
operator char();
};
void f(Y& a) {
if (a) {
// ill-formed: X::operator int() or Y::operator char()
}
}
— end example ]
15.3.1
Conversion by constructor
[class.conv.ctor]
1
A constructor declared without the function-specifier explicit specifies a conversion from the types of its
parameters (if any) to the type of its class. Such a constructor is called a converting constructor. [ Example:
struct X {
X(int);
X(const char*, int =0);
X(int, int);
};
void f(X arg) {
X a = 1;
// a = X(1)
X b = "Jessie";
// b = X("Jessie",0)
a = 2;
// a = X(2)
f(3);
// f(X(3))
f({1, 2});
// f(X(1,2))
}
— end example ]
2
[ Note: An explicit constructor constructs objects just like non-explicit constructors, but does so only where the
direct-initialization syntax (11.6) or where casts (8.5.1.9, 8.5.3) are explicitly used; see also 16.3.1.4. A default
constructor may be an explicit constructor; such a constructor will be used to perform default-initialization
or value-initialization (11.6). [ Example:
struct Z {
explicit Z();
explicit Z(int);
explicit Z(int, int);
};
Z a;
// OK: default-initialization performed
Z b{};
// OK: direct initialization syntax used
Z c = {};
// error: copy-list-initialization
Z a1 = 1;
// error: no implicit conversion
Z a3 = Z(1);
// OK: direct initialization syntax used
Z a2(1);
// OK: direct initialization syntax used
Z* p = new Z(1);
// OK: direct initialization syntax used
Z a4 = (Z)1;
// OK: explicit cast used
Z a5 = static_cast<Z>(1);
// OK: explicit cast used
Z a6 = { 3, 4 };
// error: no implicit conversion
— end example ]
— end note ]
3
A non-explicit copy/move constructor (15.8) is a converting constructor.
[Note: An implicitly-declared
copy/move constructor is not an explicit constructor; it may be called for implicit type conversions.
— end
note ]
§ 15.3.1
253
15.3.2
Conversion functions
[class.conv.fct]
1
A member function of a class X having no parameters with a name of the form
conversion-function-id:
operator conversion-type-id
conversion-type-id:
type-specifier-seq conversion-declaratoropt
conversion-declarator:
ptr-operator conversion-declaratoropt
specifies a conversion from X to the type specified by the conversion-type-id. Such functions are called
conversion functions. A decl-specifier in the decl-specifier-seq of a conversion function (if any) shall be
neither a defining-type-specifier nor static. The type of the conversion function (11.3.5) is “function taking
no parameter returning conversion-type-id”. A conversion function is never used to convert a (possibly
cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly
cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.118 [ Example:
struct X {
operator int();
operator auto() -> short;
// error: trailing return type
};
void f(X a) {
int i = int(a);
i = (int)a;
i = a;
}
In all three cases the value assigned will be converted by X::operator int().
— end example ]
2
A conversion function may be explicit (10.1.2), in which case it is only considered as a user-defined conversion
for direct-initialization (11.6). Otherwise, user-defined conversions are not restricted to use in assignments
and initializations. [ Example:
class Y { };
struct Z {
explicit operator Y() const;
};
void h(Z z) {
Y y1(z);
// OK: direct-initialization
Y y2 = z;
// ill-formed: copy-initialization
Y y3 = (Y)z;
// OK: cast notation
}
void g(X a, X b) {
int i = (a) ? 1+a : 0;
int j = (a&&b) ? a+b : i;
if (a) {
}
}
— end example ]
3
The conversion-type-id shall not represent a function type nor an array type. The conversion-type-id in a
conversion-function-id is the longest sequence of tokens that could possibly form a conversion-type-id. [ Note:
This prevents ambiguities between the declarator operator * and its expression counterparts. [ Example:
&ac.operator int*i; // syntax error:
// parsed as: &(ac.operator int *)i
// not as: &(ac.operator int)*i
118) These conversions are considered as standard conversions for the purposes of overload resolution (16.3.3.1, 16.3.3.1.4) and
therefore initialization (11.6) and explicit casts (8.5.1.9). A conversion to void does not invoke any conversion function (8.5.1.9).
Even though never directly called to perform a conversion, such conversion functions can be declared and can potentially be
reached through a call to a virtual conversion function in a base class.
§ 15.3.2
254
The * is the pointer declarator and not the multiplication operator.
— end example ] This rule also prevents
ambiguities for attributes. [ Example:
operator int [[noreturn]] ();
// error: noreturn attribute applied to a type
— end example ]
— end note ]
4
Conversion functions are inherited.
5
Conversion functions can be virtual.
6
A conversion function template shall not have a deduced return type (10.1.7.4). [ Example:
struct S {
operator auto() const { return 10; }
// OK
template<class T>
operator auto() const { return 1.2; }
// error: conversion function template
};
— end example ]
15.4
Destructors
[class.dtor]
1
In a declaration of a destructor, the declarator is a function declarator (11.3.5) of the form
ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional
surrounding parentheses, and the id-expression has one of the following forms:
(1.1)
in a member-declaration that belongs to the member-specification of a class but is not a friend
declaration (14.3), the id-expression is ~class-name and the class-name is the injected-class-name (Clause
12) of the immediately-enclosing class;
(1.2)
in a member-declaration that belongs to the member-specification of a class template but is not a
friend declaration, the id-expression is ~class-name and the class-name names the current instantiation
(17.7.2.1) of the immediately-enclosing class template; or
(1.3)
in a declaration at namespace scope or in a friend declaration, the id-expression is nested-name-specifier
~class-name and the class-name names the same class as the nested-name-specifier.
The class-name shall not be a typedef-name. A destructor shall take no arguments (11.3.5). Each decl-specifier
of the decl-specifier-seq of a destructor declaration (if any) shall be friend, inline, or virtual.
2
A destructor is used to destroy objects of its class type. The address of a destructor shall not be taken.
A destructor can be invoked for a const, volatile or const volatile object. const and volatile
semantics (10.1.7.1) are not applied on an object under destruction. They stop being in effect when the
destructor for the most derived object (6.6.2) starts.
3
[Note: A declaration of a destructor that does not have a noexcept-specifier has the same exception
specification as if had been implicitly declared (18.4).
— end note ]
4
If a class has no user-declared destructor, a destructor is implicitly declared as defaulted (11.4). An
implicitly-declared destructor is an inline public member of its class.
5
A defaulted destructor for a class X is defined as deleted if:
(5.1)
X is a union-like class that has a variant member with a non-trivial destructor,
(5.2)
any potentially constructed subobject has class type M (or array thereof) and M has a deleted destructor
or a destructor that is inaccessible from the defaulted destructor,
(5.3)
or, for a virtual destructor, lookup of the non-array deallocation function results in an ambiguity or in
a function that is deleted or inaccessible from the defaulted destructor.
6
A destructor is trivial if it is not user-provided and if:
(6.1)
the destructor is not virtual,
(6.2)
all of the direct base classes of its class have trivial destructors, and
(6.3)
for all of the non-static data members of its class that are of class type (or array thereof), each such
class has a trivial destructor.
Otherwise, the destructor is non-trivial.
§ 15.4
255
7
A destructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2) or
when it is explicitly defaulted after its first declaration.
8
Before the defaulted destructor for a class is implicitly defined, all the non-user-provided destructors for its
base classes and its non-static data members shall have been implicitly defined.
9
After executing the body of the destructor and destroying any automatic objects allocated within the body, a
destructor for class X calls the destructors for X’s direct non-variant non-static data members, the destructors
for X’s non-virtual direct base classes and, if X is the type of the most derived class (15.6.2), its destructor
calls the destructors for X’s virtual base classes. All destructors are called as if they were referenced with a
qualified name, that is, ignoring any possible virtual overriding destructors in more derived classes. Bases
and members are destroyed in the reverse order of the completion of their constructor (see 15.6.2). A return
statement (9.6.3) in a destructor might not directly return to the caller; before transferring control to the
caller, the destructors for the members and bases are called. Destructors for elements of an array are called
in reverse order of their construction (see 15.6).
10
A destructor can be declared virtual (13.3) or pure virtual (13.4); if any objects of that class or any
derived class are created in the program, the destructor shall be defined. If a class has a base class with a
virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.
11
[Note: Some language constructs have special semantics when used during destruction; see 15.7.
— end
note ]
12
A destructor is invoked implicitly
(12.1)
for a constructed object with static storage duration (6.6.4.1) at program termination (6.8.3.4),
(12.2)
for a constructed object with thread storage duration (6.6.4.2) at thread exit,
(12.3)
for a constructed object with automatic storage duration (6.6.4.3) when the block in which an object is
created exits (9.7),
(12.4)
for a constructed temporary object when its lifetime ends (7.4, 15.2).
In each case, the context of the invocation is the context of the construction of the object. A destructor is
also invoked implicitly through use of a delete-expression (8.5.2.5) for a constructed object allocated by a
new-expression (8.5.2.4); the context of the invocation is the delete-expression. [ Note: An array of class type
contains several subobjects for each of which the destructor is invoked.
— end note ] A destructor can also
be invoked explicitly. A destructor is potentially invoked if it is invoked or as specified in 8.5.2.4, 15.6.2,
and 18.1. A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from
the context of the invocation.
13
At the point of definition of a virtual destructor (including an implicit definition (15.8)), the non-array
deallocation function is determined as if for the expression delete this appearing in a non-virtual destructor
of the destructor’s class (see 8.5.2.5). If the lookup fails or if the deallocation function has a deleted
definition (11.4), the program is ill-formed. [ Note: This assures that a deallocation function corresponding
to the dynamic type of an object is available for the delete-expression (15.5).
— end note ]
14
In an explicit destructor call, the destructor is specified by a ~ followed by a type-name or decltype-specifier
that denotes the destructor’s class type. The invocation of a destructor is subject to the usual rules for
member functions (12.2.1); that is, if the object is not of the destructor’s class type and not of a class derived
from the destructor’s class type (including when the destructor is invoked via a null pointer value), the
program has undefined behavior. [ Note: Invoking delete on a null pointer does not call the destructor; see
8.5.2.5.
— end note ] [ Example:
struct B {
virtual ~B() { }
};
struct D : B {
~D() { }
};
D D_object;
typedef B B_alias;
B* B_ptr = &D_object;
void f() {
D_object.B::~B();
// calls B’s destructor
§ 15.4
256
B_ptr->~B();
// calls D’s destructor
B_ptr->~B_alias();
// calls D’s destructor
B_ptr->B_alias::~B();
// calls B’s destructor
B_ptr->B_alias::~B_alias();
// calls B’s destructor
}
— end example ] [ Note: An explicit destructor call must always be written using a member access operator
(8.5.1.5) or a qualified-id (8.4); in particular, the unary-expression ~X() in a member function is not an
explicit destructor call (8.5.2.1).
— end note ]
15
[Note: Explicit calls of destructors are rarely needed. One use of such calls is for objects placed at specific
addresses using a placement new-expression. Such use of explicit placement and destruction of objects can be
necessary to cope with dedicated hardware resources and for writing memory management facilities. For
example,
void* operator new(std::size_t, void* p) { return p; }
struct X {
X(int);
~X();
};
void f(X* p);
void g() {
// rare, specialized use:
char* buf = new char[sizeof(X)];
X* p = new(buf) X(222);
// use buf[] and initialize
f(p);
p->X::~X();
// cleanup
}
— end note ]
16
Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the
destructor is invoked for an object whose lifetime has ended (6.6.3).
[Example: If the destructor for an
automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily
invoke implicit destruction of the object, the behavior is undefined.
— end example ]
17
[ Note: The notation for explicit call of a destructor can be used for any scalar type name (8.5.1.4). Allowing
this makes it possible to write code without having to know if a destructor exists for a given type. For
example:
typedef int I;
I* p;
p->I::~I();
— end note ]
15.5
Free store
[class.free]
1
Any allocation function for a class T is a static member (even if not explicitly declared static).
2
[ Example:
class Arena;
struct B {
void* operator new(std::size_t, Arena*);
};
struct D1 : B {
};
Arena* ap;
void foo(int i) {
new (ap) D1;
// calls B::operator new(std::size_t, Arena*)
new D1[i];
// calls ::operator new[](std::size_t)
new D1;
// ill-formed: ::operator new(std::size_t) hidden
}
— end example ]
§ 15.5
257
3
When an object is deleted with a delete-expression (8.5.2.5), a deallocation function (operator delete() for
non-array objects or operator delete[]() for arrays) is (implicitly) called to reclaim the storage occupied
by the object (6.6.4.4.2).
4
Class-specific deallocation function lookup is a part of general deallocation function lookup (8.5.2.5) and
occurs as follows. If the delete-expression is used to deallocate a class object whose static type has a virtual
destructor, the deallocation function is the one selected at the point of definition of the dynamic type’s
virtual destructor (15.4).119 Otherwise, if the delete-expression is used to deallocate an object of class T or
array thereof, the static and dynamic types of the object shall be identical and the deallocation function’s
name is looked up in the scope of T. If this lookup fails to find the name, general deallocation function
lookup (8.5.2.5) continues. If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a
placement deallocation function, the program is ill-formed.
5
Any deallocation function for a class X is a static member (even if not explicitly declared static). [ Example:
class X {
void operator delete(void*);
void operator delete[](void*, std::size_t);
};
class Y {
void operator delete(void*, std::size_t);
void operator delete[](void*);
};
— end example ]
6
Since member allocation and deallocation functions are static they cannot be virtual. [Note: However,
when the cast-expression of a delete-expression refers to an object of class type, because the deallocation
function actually called is looked up in the scope of the class that is the dynamic type of the object, if the
destructor is virtual, the effect is the same. For example,
struct B {
virtual ~B();
void operator delete(void*, std::size_t);
};
struct D : B {
void operator delete(void*);
};
void f() {
B* bp = new D;
delete bp;
// 1: uses D::operator delete(void*)
}
Here, storage for the non-array object of class D is deallocated by D::operator delete(), due to the virtual
destructor.
— end note ] [ Note: Virtual destructors have no effect on the deallocation function actually called
when the cast-expression of a delete-expression refers to an array of objects of class type. For example,
struct B {
virtual ~B();
void operator delete[](void*, std::size_t);
};
struct D : B {
void operator delete[](void*, std::size_t);
};
void f(int i) {
D* dp = new D[i];
delete [] dp;
// uses D::operator delete[](void*, std::size_t)
B* bp = new D[i];
119) A similar provision is not needed for the array version of operator delete because 8.5.2.5 requires that in this situation,
the static type of the object to be deleted be the same as its dynamic type.
§ 15.5
258
delete[] bp;
// undefined behavior
}
— end note ]
7
Access to the deallocation function is checked statically. Hence, even though a different one might actually
be executed, the statically visible deallocation function is required to be accessible. [Example: For the call
on line “// 1” above, if B::operator delete() had been private, the delete expression would have been
ill-formed.
— end example ]
8
[ Note: If a deallocation function has no explicit noexcept-specifier, it has a non-throwing exception specification
(18.4).
— end note ]
15.6
Initialization
[class.init]
1
When no initializer is specified for an object of (possibly cv-qualified) class type (or array thereof), or the
initializer has the form (), the object is initialized as specified in 11.6.
2
An object of class type (or array thereof) can be explicitly initialized; see 15.6.1 and 15.6.2.
3
When an array of class objects is initialized (either explicitly or implicitly) and the elements are initialized
by constructor, the constructor shall be called for each element of the array, following the subscript order;
see 11.3.4. [ Note: Destructors for the array elements are called in reverse order of their construction.
— end
note ]
15.6.1
Explicit initialization
[class.expl.init]
1
An object of class type can be initialized with a parenthesized expression-list, where the expression-list
is construed as an argument list for a constructor that is called to initialize the object. Alternatively, a
single assignment-expression can be specified as an initializer using the = form of initialization. Either
direct-initialization semantics or copy-initialization semantics apply; see 11.6. [ Example:
struct complex {
complex();
complex(double);
complex(double,double);
};
complex sqrt(complex,complex);
complex a(1);
// initialize by a call of complex(double)
complex b = a;
// initialize by a copy of a
complex c = complex(1,2);
// construct complex(1,2) using complex(double,double),
// copy/move it into c
complex d = sqrt(b,c);
// call sqrt(complex,complex) and copy/move the result into d
complex e;
// initialize by a call of complex()
complex f = 3;
// construct complex(3) using complex(double), copy/move it into f
complex g = { 1, 2 };
// initialize by a call of complex(double, double)
— end example ] [ Note: Overloading of the assignment operator (16.5.3) has no effect on initialization.
— end
note ]
2
An object of class type can also be initialized by a braced-init-list. List-initialization semantics apply; see 11.6
and 11.6.4. [ Example:
complex v[6] = { 1, complex(1,2), complex(), 2 };
Here, complex::complex(double) is called for the initialization of v[0] and v[3], complex::complex(
double, double) is called for the initialization of v[1], complex::complex() is called for the initialization
v[2], v[4], and v[5]. For another example,
struct X {
int i;
float f;
complex c;
} x = { 99, 88.8, 77.7 };
Here, x.i is initialized with 99, x.f is initialized with 88.8, and complex::complex(double) is called for the
initialization of x.c.
— end example ] [Note: Braces can be elided in the initializer-list for any aggregate,
§ 15.6.1
259
even if the aggregate has members of a class type with user-defined type conversions; see 11.6.1.
— end
note ]
3
[Note: If T is a class type with no default constructor, any declaration of an object of type T (or array
thereof) is ill-formed if no initializer is explicitly specified (see 15.6 and 11.6).
— end note ]
4
[ Note: The order in which objects with static or thread storage duration are initialized is described in 6.8.3.3
and 9.7.
— end note ]
15.6.2
Initializing bases and members
[class.base.init]
1
In the definition of a constructor for a class, initializers for direct and virtual base class subobjects and
non-static data members can be specified by a ctor-initializer, which has the form
ctor-initializer:
: mem-initializer-list
mem-initializer-list:
mem-initializer ...opt
mem-initializer-list , mem-initializer ...opt
mem-initializer:
mem-initializer-id ( expression-listopt )
mem-initializer-id braced-init-list
mem-initializer-id:
class-or-decltype
identifier
2
In a mem-initializer-id an initial unqualified identifier is looked up in the scope of the constructor’s class
and, if not found in that scope, it is looked up in the scope containing the constructor’s definition. [Note:
If the constructor’s class contains a member with the same name as a direct or virtual base class of the
class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to
the class member. A mem-initializer-id for the hidden base class may be specified using a qualified name.
— end note ] Unless the mem-initializer-id names the constructor’s class, a non-static data member of the
constructor’s class, or a direct or virtual base of that class, the mem-initializer is ill-formed.
3
A mem-initializer-list can initialize a base class using any class-or-decltype that denotes that base class type.
[ Example:
struct A { A(); };
typedef A global_A;
struct B { };
struct C: public A, public B { C(); };
C::C(): global_A() { }
// mem-initializer for base A
— end example ]
4
If a mem-initializer-id is ambiguous because it designates both a direct non-virtual base class and an inherited
virtual base class, the mem-initializer is ill-formed. [ Example:
struct A { A(); };
struct B: public virtual A { };
struct C: public A, public B { C(); };
C::C(): A() { }
// ill-formed: which A?
— end example ]
5
A ctor-initializer may initialize a variant member of the constructor’s class. If a ctor-initializer specifies more
than one mem-initializer for the same member or for the same base class, the ctor-initializer is ill-formed.
6
A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-or-decltype
that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class, it shall
be the only mem-initializer; the constructor is a delegating constructor, and the constructor selected by the
mem-initializer is the target constructor. The target constructor is selected by overload resolution. Once the
target constructor returns, the body of the delegating constructor is executed. If a constructor delegates to
itself directly or indirectly, the program is ill-formed, no diagnostic required. [ Example:
struct C {
C( int ) { }
// #1: non-delegating constructor
C(): C(42) { }
// #2: delegates to #1
C( char c ) : C(42.0) { }
// #3: ill-formed due to recursion with #4
§ 15.6.2
260
C( double d ) : C(’a’) { }
// #4: ill-formed due to recursion with #3
};
— end example ]
7
The expression-list or braced-init-list in a mem-initializer is used to initialize the designated subobject (or, in
the case of a delegating constructor, the complete class object) according to the initialization rules of 11.6 for
direct-initialization. [ Example:
struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
D(int);
B1 b;
const int c;
};
D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ }
D d(10);
— end example ]
[Note: The initialization performed by each mem-initializer constitutes a full-expres-
sion (6.8.1). Any expression in a mem-initializer is evaluated as part of the full-expression that performs the
initialization.
— end note ] A mem-initializer where the mem-initializer-id denotes a virtual base class is
ignored during execution of a constructor of any class that is not the most derived class.
8
A temporary expression bound to a reference member in a mem-initializer is ill-formed. [ Example:
struct A {
A() : v(42) { }
// error
const int& v;
};
— end example ]
9
In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-
initializer-id
(including the case where there is no mem-initializer-list because the constructor has no
ctor-initializer ), then
(9.1)
if the entity is a non-static data member that has a default member initializer (12.2) and either
(9.1.1)
the constructor’s class is a union (12.3), and no other variant member of that union is designated
by a mem-initializer-id or
(9.1.2)
the constructor’s class is not a union, and, if the entity is a member of an anonymous union, no
other member of that union is designated by a mem-initializer-id,
the entity is initialized from its default member initializer as specified in 11.6;
(9.2)
otherwise, if the entity is an anonymous union or a variant member (12.3.1), no initialization is
performed;
(9.3)
otherwise, the entity is default-initialized (11.6).
[Note: An abstract class (13.4) is never a most derived class, thus its constructors never initialize virtual
base classes, therefore the corresponding mem-initializers may be omitted.
— end note ] An attempt to
initialize more than one non-static data member of a union renders the program ill-formed. [ Note: After the
call to a constructor for class X for an object with automatic or dynamic storage duration has completed, if
the constructor was not invoked as part of value-initialization and a member of X is neither initialized nor
given a value during execution of the compound-statement of the body of the constructor, the member has an
indeterminate value.
— end note ] [ Example:
struct A {
A();
};
struct B {
B(int);
};
struct C {
C() { }
// initializes members as follows:
§ 15.6.2
261

 

 

 

 

 

 

 

Content      ..     7      8      9      10     ..