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.