Friend Functions

Friend functions are not considered class members; they are normal external functions that are given special access privileges. Friends are not in the class's scope, and they are not called using the member-selection operators (. and –>) unless they are members of another class. The following example shows a Point class and an overloaded operator, operator+. (This example primarily illustrates friends, not overloaded operators. For more information about overloaded operators, see “Overloaded Operators” in Chapter 12, on topic .)

#include <iostream.h>

// Declare class Point.

class Point

{

public:

// Constructors

Point() { _x = _y = 0; }

Point( unsigned x, unsigned y ) { _x = x; _y = y; }

// Accessors

unsigned x() { return _x; }

unsigned y() { return _y; }

void Print() { cout << "Point(" << _x << ", " << _y << ")"

<< endl; }

// Friend function declarations

friend Point operator+( Point& pt, int nOffset );

friend Point operator+( int nOffset, Point& pt );

private:

unsigned _x;

unsigned _y;

};

// Friend-function definitions

//

// Handle Point + int expression.

Point operator+( Point& pt, int nOffset )

{

Point ptTemp = pt;

// Change private members _x and _y directly.

ptTemp._x += nOffset;

ptTemp._y += nOffset;

return ptTemp;

}

// Handle int + Point expression.

Point operator+( int nOffset, Point& pt )

{

Point ptTemp = pt;

// Change private members _x and _y directly.

ptTemp._x += nOffset;

ptTemp._y += nOffset;

return ptTemp;

}

// Test overloaded operator.

main()

{

Point pt( 10, 20 );

pt.Print();

pt = pt + 3; // Point + int

pt.Print();

pt = 3 + pt; // int + Point

pt.Print();

return 0;

}

When the expression pt + 3 is encountered in the main function, the compiler determines if an appropriate user-defined operator+ exists. In this case, the function operator+( Point pt, int nOffset ) matches the operands, and a call tothe function is issued. In the second case (the expression 3 + pt), the function operator+( Point pt, int nOffset ) matches the supplied operands. Therefore, supplying these two forms of operator+ preserves the commutative properties of the + operator.

A user-defined operator+ can be written as a member function, but it takes only one argument: the value to be added to the object. As a result, the commutative properties of addition cannot be correctly implemented with member functions; they must use friend functions instead.

Notice that both versions of the overloaded operator+ function are declared as friends in class Point. Both declarations are necessary—when friend declarations name overloaded functions or operators, only the particular functions specified by the argument types become friends. Suppose a third operator+ function were declared as follows:

Point &operator+( Point &pt, Point &pt );

The operator+ function in the preceding example is not a friend of class Point simply because it has the same name as two other functions that are declared as friends.

Because friend declarations are unaffected by access specifiers, they can be declared in any section of the class declaration.