Go to the first, previous, next, last section, table of contents.

7.12 Specifying Friends

Larch/C++ can also specify friendship grants, which record information that may be needed in an implementation. Friendship grants, as in C++, grant access to the private interface of a class implementation to particular functions or to all the member function in some class (see section 11.4 of [Ellis-Stroustrup90]).

For Larch/C++, a friendship grant in a class specification also grants accessibility to the private and protected members in the specification of the functions granted access (see section 2.3 Accessibility of Class Members in Specifications).

A class specification may specify a friendship grant with a member-declarator or a member-declaration, starting with the decl-specifier friend. The syntax is the same as in C++. See section 7.2 Class Member Specifications for the syntax of member-declarator and member-declaration. See section 5.2 Declaration Specifiers for the syntax of decl-specifier.

For example, adding the following to the specification of Money, (see section 7.1.2 A Design with a Nontrivial Trait (Money)) would grant friendship to operator *= with parameters of types Money& and double.

friend Money& operator *= (Money& p, double scalar);

Since friendship grants are not themselves affected by their placement in the public, private, or protected sections of a specification, they may appear anywhere a member-declarator may appear (see section 7 Class Specifications for the syntax).

The specification of a function granted friendship cannot appear inside the class. For example, the specification of the overload of *= for Money& and double parameters could not be given in the class Money. Instead, it would appear elsewhere. For example, it could be given in a separate specification module, such as the following.

// @(#)$Id: MoneyOpStar.lh,v 1.6 1997/06/03 20:29:44 leavens Exp $
#include "Money.lh"
extern Money& operator *= (Money& p, double scalar) throw();
//@ behavior {
//@   requires assigned(p, pre);
//@   ensures result = p /\ p' = scalar * p^;
//@ }

An implementation of a Larch/C++ specification may have more friendship grants than appear in the specification. This is because a friendship grant records a C++ design decision (see section 10.3 Specifying Protected and Private Interfaces for more discussion on this point). This means that you may specify a function which might be granted friendship in some implementation, without giving the friendship grant in the specification. For example, one might specify *= as above, and implement it as a friend function by granting it friendship in the code, all without writing the friendship grant in the specification of Money. Thus the friendship grant is only needed in the specification if one wishes to explicitly record a detailed design decision.

Although Larch/C++ fully supports the granting of friendship as a way to record detailed design decisions, friendship grants are necessary far less often than some C++ programmers think. This is especially the case for overloads of << for output. As a general rule, you should try to specify enough member functions so that << can be programmed without access to private data members, and thus without a friendship grant. When specifying for clients (as opposed to recording detailed design), you should only put a friendship grant in the Larch/C++ specification when it is clear that the friendship grant will be needed in every conceivable implementation.

Go to the first, previous, next, last section, table of contents.