This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

167
cppdraft/class/friend.md Normal file
View File

@@ -0,0 +1,167 @@
[class.friend]
# 11 Classes [[class]](./#class)
## 11.8 Member access control [[class.access]](class.access#class.friend)
### 11.8.4 Friends [class.friend]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4916)
A friend of a class is a function or class that is
given permission to name the private and protected members of the class[.](#1.sentence-1)
A class specifies its friends, if any, by way of friend declarations[.](#1.sentence-2)
Such declarations give special access rights to the friends, but they
do not make the nominated friends members of the befriending class[.](#1.sentence-3)
[*Example [1](#example-1)*:
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](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4946)
Declaring a class to be a friend implies that private and
protected members of the class granting friendship can be named in the[*base-specifier*](class.derived.general#nt:base-specifier "11.7.1General[class.derived.general]")*s* and member declarations of the befriended
class[.](#2.sentence-1)
[*Example [2](#example-2)*: 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 friendclass Y { A::B my; // OK, A::B accessible to nested member of friend};}; — *end example*]
[*Example [3](#example-3)*: 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*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4984)
A friend declaration that does not declare a function
shall be a [*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1General[class.mem.general]")[.](#3.sentence-1)
[*Note [1](#note-1)*:
A friend declaration can be the[*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") in
a [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") ([[temp.pre]](temp.pre "13.1Preamble"), [[temp.friend]](temp.friend "13.7.5Friends"))[.](#3.sentence-2)
— *end note*]
If a [*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1General[class.mem.general]") in a friend declaration
designates a (possibly
cv-qualified) class type, that class is declared as a friend; otherwise, the[*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1General[class.mem.general]") is ignored[.](#3.sentence-3)
[*Example [4](#example-4)*: class C;typedef C Ct;class E;
class X1 {friend C; // OK, class C is a friend};
class X2 {friend Ct; // OK, class C is a friendfriend D; // error: D not foundfriend class D; // OK, elaborated-type-specifier declares new class};
template <typename ... Ts> class R {friend Ts...;};
template <class... Ts, class... Us>class R<R<Ts...>, R<Us...>> {friend Ts::Nested..., Us...;};
R<C> rc; // class C is a friend of R<C> R<C, E> rce; // classes C and E are friends of R<C, E> R<int> Ri; // OK, “friend int;'' is ignoredstruct E { struct Nested; };
R<R<E>, R<C, int>> rr; // E::Nested and C are friends of R<R<E>, R<C, int>> — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5032)
[*Note [2](#note-2)*:
A friend declaration refers to an entity, not (all overloads of) a name[.](#4.sentence-1)
A member function of a classX can be a friend of
a classY[.](#4.sentence-2)
[*Example [5](#example-5)*: class Y {friend char* X::foo(int); friend X::X(char); // constructors can be friendsfriend X::~X(); // destructors can be friends}; — *end example*]
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5053)
A function may be defined in a friend declaration of a class if and only if the
class is a non-local class ([[class.local]](class.local "11.6Local class declarations")) and the function name is unqualified[.](#5.sentence-1)
[*Example [6](#example-6)*: class M {friend void f() { } // definition of global f, a friend of M,// not the definition of a member function}; — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5066)
Such a function is implicitly an inline ([[dcl.inline]](dcl.inline "9.2.8The inline specifier")) function
if it is attached to the global module[.](#6.sentence-1)
[*Note [3](#note-3)*:
If a friend function is defined outside a class,
it is not in the scope of the class[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5074)
No[*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage class specifiers[dcl.stc]") shall appear in the[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") of a friend declaration[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5081)
A member nominated by a friend declaration shall be accessible in the
class containing the friend declaration[.](#8.sentence-1)
The meaning of the friend declaration is the same whether the friend declaration
appears in the private, protected, or public ([[class.mem]](class.mem "11.4Class members"))
portion of the class[*member-specification*](class.mem.general#nt:member-specification "11.4.1General[class.mem.general]")[.](#8.sentence-2)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5090)
Friendship is neither inherited nor transitive[.](#9.sentence-1)
[*Example [7](#example-7)*: 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*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5118)
[*Note [4](#note-4)*:
A friend declaration never binds any names ([[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators"), [[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))[.](#10.sentence-1)
— *end note*]
[*Example [8](#example-8)*: // Assume f and g have not yet been declared.void h(int);template <class T> void f2(T);namespace A {class X {friend void f(X); // A::f(X) is a friendclass Y {friend void g(); // A::g is a friendfriend void h(int); // A::h is a friend// ::h not consideredfriend void f2<>(int); // ::f2<>(int) is a friend}; }; // A::f, A::g and A::h are not visible here X x; void g() { f(x); } // definition of A::gvoid f(X) { /* ... */ } // definition of A::fvoid h(int) { /* ... */ } // definition of A::h// A::f, A::g and A::h are visible here and known to be friends}using A::x;
void h() { A::f(x);
A::X::f(x); // error: f is not a member of A::X A::X::Y::g(); // error: g is not a member of A::X::Y} — *end example*]
[*Example [9](#example-9)*: class X;void a();void f() {class Y; extern void b(); class A {friend class X; // OK, but X is a local class, not ::Xfriend class Y; // OKfriend class Z; // OK, introduces local class Zfriend void a(); // error, ::a is not consideredfriend void b(); // OKfriend void c(); // error};
X* px; // OK, but ::X is found Z* pz; // error: no Z is found} — *end example*]