Friend Scope in C++

Friend scope in C++

Friendship in C++ is not transitive:

John is a friend of mine and he can use my wireless connection any time (I trust him).

John's friend Tim though is a waster and though John is my friend I do not include Tim as a friend, and thus I don't let him use my wireless connection.

Friendship is NOT inherited

Also John's children are a bunch of hooligans so I don't trust them either they are definitely not my friends nor are my own children who I trust as far as I could throw them.

Though our children can not directly accesses the wireless they can get access to it if they go through us. So John's children can access my wireless if they access it via John (ie they are supervised and protected by John).

Also, friendship is not symmetric.

John has a goverment job so he unfortunately is not allowed to trust anyone, especially when it comes to wireless.

You are always your own best friend.

This allows things like copy constructors where you can access the private member of another object even though there is no real accesses.

So I am also automatically friends with all my clones :-) as they are just other instances of myself.

How to declare a global-scope function a friend to a namespaced class?

You can reference the global scope with just ::. So your friend declaration can be:

friend void ::func( union sigval );

But don't forget to forward declare the function before you reference it in the class!

So in the global scope you'll need:

void func( union sigval );

Before the class declaration.

Compiled example: https://ideone.com/hDHDJ8

When should you use 'friend' in C++?

Firstly (IMO) don't listen to people who say friend is not useful. It IS useful. In many situations you will have objects with data or functionality that are not intended to be publicly available. This is particularly true of large codebases with many authors who may only be superficially familiar with different areas.

There ARE alternatives to the friend specifier, but often they are cumbersome (cpp-level concrete classes/masked typedefs) or not foolproof (comments or function name conventions).

Onto the answer;

The friend specifier allows the designated class access to protected data or functionality within the class making the friend statement. For example in the below code anyone may ask a child for their name, but only the mother and the child may change the name.

You can take this simple example further by considering a more complex class such as a Window. Quite likely a Window will have many function/data elements that should not be publicly accessible, but ARE needed by a related class such as a WindowManager.

class Child
{
//Mother class members can access the private parts of class Child.
friend class Mother;

public:

string name( void );

protected:

void setName( string newName );
};

What's the scope of inline friend functions?

When you declare a friend function with an unqualified id in a class it names a function in the nearest enclosing namespace scope.

If that function hasn't previously been declared then the friend declaration doesn't make that function visible in that scope for normal lookup. It does make the declared function visible to argument-dependent lookup.

This is emphasised in many notes, but the definitive statement is in 7.3.1.2/3 (of ISO/IEC 14882:2011):

Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship). If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2). If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.

Scope of friend function in GCC

The quote means that the following works - the code is in the lexical scope of the class, such that unqualified name lookup will behave specially

class A
{
typedef int type;

friend void function() {
type foo; /* type is visible */
};
};

If you had defined "function" in the namespace scope, then "type" would not be visible - you would have to say "A::type". That's why it says in the next sentence "A friend function defined outside the class is not.". Unqualified name lookup for an in-class definition is stated as

Name lookup for a name used in the definition of a friend function (11.4) defined inline in the class
granting friendship shall proceed as described for lookup in member function definitions. If the friend
function is not defined in the class granting friendship, name lookup in the friend function definition
shall proceed as described for lookup in namespace member function definitions.

So the text you quoted is not really required to be normative - the specification of unqualified name-lookup already covers it.

Friend function is not visible in the class

The friend declaration states that a function called f in the surrounding namespace is a friend of the class; but it does not introduce the name f into the namespace. It's not available (except by argument-dependent lookup) until it's been declared in the namespace.

The relevant rule is C++11 7.3.1.2/3:

If a friend declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup or by qualified lookup until a matching declaration is provided in that namespace scope.



Related Topics



Leave a reply



Submit