class X { int a; // X::a is private by default }; struct S { int a; // S::a is public by default };
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 }
class A {
typedef int I; // private member
I f();
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 { };
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
access-specifier : member-specificationAn access-specifier specifies the access rules for members following it until the end of the class or until another access-specifier is encountered.
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 };
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 public: int d; // S::d is public };
struct S { class A; enum E : int; private: class A { }; // error: cannot change access enum E: int { e0 }; // error: cannot change access };
class A { }; class B : private A { }; class C : public B { A* p; // error: injected-class-name A is inaccessible ::A* q; // OK };
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 { /* ... */ };
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. }
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. } };
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
}
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); }
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 }; };
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 };
class A {
friend class B { }; // error: cannot define class in friend declaration
};
friend elaborated-type-specifier ; friend simple-type-specifier ; friend typename-specifier ;
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
class Y { friend char* X::foo(int); friend X::X(char); // constructors can be friends friend X::~X(); // destructors can be friends };
class M { friend void f() { } // definition of global f, a friend of M, // not the definition of a member function };
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 } };
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 }
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 }
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(); // OK: B::f() is public, D::f() is invoked pd->f(); // error: D::f() is private }
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 } };