friend declaration
The friend declaration appears in a class body and grants a function or another class access to private and protected members of the class where the friend declaration appears.
Contents |
[edit] Syntax
friend function-declaration
|
(1) | ||||||||
friend function-definition
|
(2) | ||||||||
friend type-specifier ;
|
(3) | ||||||||
friend elaborated-class-name ;
|
(4) | ||||||||
[edit] Description
class Y { int data; // private member // the non-member function operator<< will have access to Y's private members friend std::ostream& operator<<(std::ostream& out, const Y& o); friend char* X::foo(int); // members of other classes can be friends too friend X::X(char), X::~X(); // constructors and destructors can be friends }; // friend declaration does not declare a member function // this operator<< still needs to be defined, as a non-member std::ostream& operator<<(std::ostream& out, const Y& y) { return out << y.data; // can access private member Y::data }
class X { int a; friend void friend_set(X& p, int a) { p.a = i; // this is a non-member function } public: void member_set(int a) { a = i; // this is a member function } };
class
, struct
, or union
followed by class name).
class Y {}; class A { int data; // private data member class B { }; // private nested type enum { a = 100 }; // private enumerator friend Y; // friend class declaration friend class X; // friend class forward declaration }; class 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 }; int v[A::a]; // OK: A::a accessible to member of friend };
[edit] Notes
Friendship is not transitive (a friend of your friend is not your friend)
Friendship is not inherited (your friend's children are not your friends)
Storage class specifiers are not allowed in friend function declarations. A function that is defined in the friend declaration has external linkage, a function that was previously defined, keeps the linkage it was defined with.
Access specifiers have no effect on the meaning of friend declarations (they can appear in private:
or in public:
sections, with no difference)
A friend class declaration cannot define a new class (friend class X {}; is an error)
When a local class declares an unqualified function or class as a friend, only functions and classes in the innermost non-class scope are looked up, not the global functions:
class F {}; int f(); int main() { extern int g(); class Local { // Local class in the main() function friend int f(); // Error, no such function declared in main() friend int g(); // OK, there is a declaration for g in main() friend class F; // friends a local F (defined later) friend class ::F; // friends the global F }; class F {}; // local F }
This section is incomplete Reason: template friends |
[edit] Example
stream insertion and extraction operators are often declared as non-member friends
#include <iostream> #include <sstream> class MyClass { int i; friend std::ostream& operator<<(std::ostream& out, const MyClass& o); friend std::istream& operator>>(std::istream& in, MyClass& o); public: MyClass(int i = 0) : i(i) {} }; std::ostream& operator<<(std::ostream& out, const MyClass& mc) { return out << mc.i; } std::istream& operator>>(std::istream& in, MyClass& mc) { return in >> mc.i; } int main() { MyClass mc(7); std::cout << mc << '\n'; std::istringstream("100") >> mc; std::cout << mc << '\n'; }
Output:
7 100
[edit] See Also
Class declaration | |
Access specifiers |