Стандарт C++ 98 (1119566), страница 52
Текст из файла (страница 52)
[Example:__________________101) The class-key of the elaborated-type-specifier is required.180© ISO/IECISO/IEC 14882:1998(E)11 Member access control11.4 Friendsclass Y {friend char* X::foo(int);// ...};—end example]5A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8),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] Such a function is implicitly inline.
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 (3.4.1).6No storage-class-specifier shall appear in the decl-specifier-seq of a friend declaration.7A name nominated by a friend declaration shall be accessible in the scope of the class containing the frienddeclaration.
The meaning of the friend declaration is the same whether the friend declaration appears in theprivate, protected or public (9.2) portion of the class member-specification.8Friendship 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 Bvoid f(A* p){p->a++;{// error: D is not a friend of A// despite being derived from a friend}};—end example]9If a friend declaration appears in a local class (9.8) and the name specified is an unqualified name, a priordeclaration is looked up without considering scopes that are outside the innermost enclosing non-classscope. For a friend function declaration, if there is no prior declaration, the program is ill-formed.
For afriend class declaration, if there is no prior declaration, the class that is specified belongs to the innermostenclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until amatching declaration is provided in the innermost enclosing nonclass scope. [Example:181ISO/IEC 14882:1998(E)© ISO/IEC11.4 Friendsclass X;void a();void f() {class Y;extern void b();class A {friend class X;friend class Y;friend class Z;friend void a();friend void b();friend void c();};X *px;Z *pz;}11 Member access control// OK, but X is a local class, not ::X// OK// OK, introduces local class Z// error, ::a is not considered// OK// error// OK, but ::X is found// error, no Z is found—end example]11.5 Protected member access1[class.protected]When a friend or a member function of a derived class references a protected nonstatic member of a baseclass, an access check applies in addition to those described earlier in clause 11.102) Except when forming apointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derivedclass itself (or any class derived from that class) (5.2.5).
If the access is to form a pointer to member, thenested-name-specifier shall name the derived class (or any class derived from that class). [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;p1->i = 2;p2->i = 3;p2->B::i = 4;int B::* pmi_B = &B::i;int B::* pmi_B2 = &D2::i;B::j = 5;D2::j =6;// ill-formed// ill-formed// OK (access through a D2)// OK (access through a D2, even though// naming class is B)// ill-formed// OK (type of &D2::i is int B::*)// OK (because refers to static member)// OK (because refers to static member)}__________________102) This additional check does not apply to other members, e.g. static data members or enumerator member constants.182© ISO/IECISO/IEC 14882:1998(E)11 Member access controlvoid D2::mem(B* pb, D1* p1){pb->i = 1;p1->i = 2;i = 3;B::i = 4;int B::* pmi_B = &B::i;int B::* pmi_B2 = &D2::i;j = 5;B::j = 6;}void g(B*{pb->ip1->ip2->i}11.5 Protected member access// ill-formed// ill-formed// OK (access through this)// OK (access through this, qualification ignored)// ill-formed// OK// OK (because j refers to static member)// OK (because B::j refers to static member)pb, D1* p1, D2* p2)= 1;= 2;= 3;// ill-formed// ill-formed// ill-formed—end example]11.6 Access to virtual functions1[class.access.virt]The access rules (clause 11) for a virtual function are determined by its declaration and are not affected bythe rules for a function that later overrides it.
[Example:class B {public:virtual int f();};class D : public B {private:int f();};void f(){D d;B* pb = &d;D* pd = &d;pb->f();pd->f();// OK: B::f() is public,// D::f() is invoked// error: D::f() is private}—end example] Access is checked at the call point using the type of the expression used to denote theobject 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.11.7 Multiple access1[class.paths]If a name can be reached by several paths through a multiple inheritance graph, the access is that of the paththat gives most access. [Example:183ISO/IEC 14882:1998(E)© ISO/IEC11.7 Multiple access11 Member access controlclass 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.
]11.8 Nested classes1[class.access.nest]The members of a nested class have no special access to members of an enclosing class, nor to classes orfunctions that have granted friendship to an enclosing class; the usual access rules (clause 11) shall beobeyed. The members of an enclosing class have no special access to members of a nested class; the usualaccess rules (clause 11) shall be obeyed. [Example:class E {int x;class B { };class I {B b;int y;void f(E* p, int i){p->x = i;}};int g(I* p){return p->y;}// error: E::B is private// error: E::x is private// error: I::y is private};—end example]2[Note: because a base-clause for a nested class is part of the declaration of the nested class itself (and notpart of the declarations of the members of the nested class), the base-clause may refer to the private members of the enclosing class.
For example,class C {class A { };A *p;class B : A{AC::ABC::B};};—end note]184// OK// OK*q;*r;*s;*t;// OK because of injection of name A in A// error, C::A is inaccessible// OK because of injection of name B in B// error, C::B is inaccessible© ISO/IECISO/IEC 14882:1998(E)12 Special member functions1[special]The default constructor (12.1), copy constructor and copy assignment operator (12.8), and destructor (12.4)are special member functions. The implementation will implicitly declare these member functions for aclass type when the program does not explicitly declare them, except as noted in 12.1.
The implementationwill implicitly define them if they are used, as specified in 12.1, 12.4 and 12.8. Programs shall not defineimplicitly-declared special member functions. Programs may explicitly refer to implicitly declared specialmember 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-formedreturn *this;}—end example] [Note: the special member functions affect the way objects of class type are created,copied, and destroyed, and how values can be converted to values of other types.
Often such special member functions are called implicitly. ]2Special member functions obey the usual access rules (clause 11). [Example: declaring a constructorprotected ensures that only derived classes and friends can create objects using it. ]12.1 Constructors1[class.ctor]Constructors do not have names. A special declarator syntax using an optional function-specifier (7.1.2)followed by the constructor’s class name followed by a parameter list is used to declare or define the constructor. In such a declaration, optional parentheses around the constructor class name are ignored.
[Example:class C {public:C();};C::C() { }// declares the constructor// defines the constructor—end example]2A constructor is used to initialize objects of its class type. Because constructors do not have names, theyare never found during name lookup; however an explicit type conversion using the functional notation(5.2.3) will cause a constructor to be called to initialize an object. [Note: for initialization of objects ofclass type see 12.6. ]3A typedef-name that names a class is a class-name (7.1.3); however, a typedef-name that names a class shallnot be used as the identifier in the declarator for a constructor declaration.4A constructor shall not be virtual (10.3) or static (9.4).
A constructor can be invoked for a const,volatile or const volatile object. A constructor shall not be declared const, volatile, orconst volatile (9.3.2). const and volatile semantics (7.1.5.1) are not applied on an object underconstruction. Such semantics only come into effect once the constructor for the most derived object (1.8)ends.185ISO/IEC 14882:1998(E)12.1 Constructors5© ISO/IEC12 Special member functionsA default constructor for a class X is a constructor of class X that can be called without an argument. Ifthere is no user-declared constructor for class X, a default constructor is implicitly declared. An implicitlydeclared default constructor is an inline public member of its class.
A constructor is trivial if it is animplicitly-declared default constructor and if:— its class has no virtual functions (10.3) and no virtual base classes (10.1), and— all the direct base classes of its class have trivial constructors, and— for all the nonstatic data members of its class that are of class type (or array thereof), each such class hasa trivial constructor.6Otherwise, the constructor is non-trivial.7An implicitly-declared default constructor for a class is implicitly defined when it is used to create an objectof its class type (1.8).
The implicitly-defined default constructor performs the set of initializations of theclass that would be performed by a user-written default constructor for that class with an empty meminitializer-list (12.6.2) and an empty function body. If that user-written default constructor would be illformed, the program is ill-formed. Before the implicitly-declared default constructor for a class is implicitly defined, all the implicitly-declared default constructors for its base classes and its nonstatic data members shall have been implicitly defined. [Note: an implicitly-declared default constructor has an exceptionspecification (15.4).