black@blake.u.washington.edu (Jim Black) (02/13/91)
Regarding "inheriting friendship", which is not supported by C++ today -- (a) The problem As acknowledged in the ARM, not being able to inherit friendship can be awkward. For instance: class Collection { // abstract class friend class Iterator; // .. }; class Iterator { // (works for all collections) friend class Collection; // .. }; Different collections (Set etc) inherit from Collection, and each would provide it's own way of initializing and stepping the Iterator. That is why a Collection is a friend of Iterator ... but we *lose* this friendship for all classes derived from Collection in C++ today. On the other hand, Stroustrup notes the following problem if C++ allowed friends to be inherited (ARM section 11.4) : class ReallySecure { friend class Trusted; // .. }; class TrustedUser { // .. }; class Spy : public TrustedUser // aha! }; (b) Solutions? So the main question is, is there a way to resolve these two conflicting purposes of "friend" (and is it worth the trouble)? Here is one way that seems possible to me. I'd appreciate comments about it, or alternate suggestions: => Could access specifiers "private" and "protected" be used to allow more flexible access-rights for friendship? => Specifically, could "protected friend class C" be used to grant friendship to class C *and* classes derived from C? (This would be a language extension, of course. It's my understanding, though, that these access keywords don't have meaning for friend declarations at present. If they do, this doesn't work...) (Note the access specifier where class friendship is granted would apply to the target/friend, not the class granting friendship: you'd grant friendship and _also_ grant propogation-rights with regard to that friendship.) In this sense, all friends in C++ today are "private" by default (access is not inherited), and the "ReallySecure" example above would still not compile, as desired. But the Iterator example above could now be coded: class Iterator { protected friend class Collection; // now Collection & all *Collection* subtypes are friends // .. }; Is this feasible, brain-dead, or what? -- Jim Black (black@blake.u.washington.edu)