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.