tags:

views:

268

answers:

4

For the example under Friend Functions
How is the following true?

"Notice that neither in the declaration of duplicate() nor in its later use in main() have we considered duplicate a member of class CRectangle. It isn't! It simply has access to its private and protected members without being a member."

Duplicate is declared in the public section of CRectangle. How is it not a member function and set_values is?

Is this a good example? Any better ones if not?

+6  A: 

Any function declared or defined as friend inside a class is not a member of that class. It's just a friend function.

That said, if a friend function is also defined within the class, it will be found by ADL lookups involving that class (which is normally used for overloaded operators).

Pavel Minaev
+3  A: 

Pavel's answer is the direct answer to your question, but I think maybe you are unclear on what a friend function is used for so I thought I'd give a common example.

A common use of friend functions is in overloading stream operators, where the specific operator needs access (or is facilitated by access) to private members of the object. Ie:

class Rectangle
{
...
    friend ostream &operator<<(ostream &stream, Rectangle r);
private:
    int width;
    int height;
};

friend ostream &operator<<(ostream &stream, Rectangle r)
{
    return (stream << "{" << width << ", " << height << "}");
}

In this case the friend function allows us to access private data for printing without have to write 'get' methods for the data. Maybe this helps clarify why friend functions are used.

DeusAduro
A good answer, and it might be worth pointing out that `friend operator<<` could even be defined entirely inside `Rectangle` - i.e., complete with the body - with semantics remaining the same.
Pavel Minaev
+1  A: 

The answer is in the friend keyword right before the function declaration in the class.

i.e. friend CRectangle duplicate (CRectangle);

A friend function is simply a function that is allowed access to the classes private member variables. It is not a member function belonging to that class.

set_values is a member of that class because it has no friend keyword and it's scope is within the class definition. The method body is defined outside the class definition. i.e. the class is like a forward definition with the implementation to follow (which is below).

By prefixing the method name with CRectangle:: we're telling the compiler that this is the implementation of the set_values function declared within the scope of the CRectangle class.

DeusAduro's answer about where friend can be useful is a very common use of friend classes.

Matt H
+1  A: 

Ok, I'll take a crack at this too.

As pointed out by everyone, the syntactic difference between a declaration of a member function and a friend function is, reasonably enough, the friend keyword.

Here is one way to think about this. A member function has an implicit parameter: the pointer to the object itself. E. g. inside set_values you can use the members width and height, and they would be the members of the object whose set_values was called.

On the other hand, you cannot use identifiers width or height by themselves inside duplicate(), because it is not a member function, and therefore it does not have the implicit parameter, i. e. it is not associated with any particular object. What friendship means, is that duplicate() has access to the private members of any CRectangle object which is passed to it, or which is a local variable within its scope.

Another point: the friend declaration is not even really a declaration of the function. It is simply a note to the compiler that if this particular function is ever defined, it is to be given access to the private members of this class.

Dima
Static member functions are still member functions, however, even though they don't have any implicit parameters. Also, while a friend declaration does not declare a function, a friend _inline definition_ both declares and defines a function (and also makes it a `friend`).
Pavel Minaev
Ah, now it's really getting interesting. :) Member functions: have an implicit parameter and have access to private static and non-static members. Static member functions: don't have an implicit parameter and can only access static data members. Friend functions: no implicit parameter, can access private static and non-static members. Great point about the inline friend functions, by the way.
Dima