Path: utzoo!attcan!uunet!odi!dlw From: dlw@odi.UUCP (Dan Weinreb) Newsgroups: comp.lang.c++ Subject: Re: Needed : Recommendations for C++ texts for beginner Message-ID: <300@odi.UUCP> Date: 16 Apr 89 06:04:52 GMT References: <1194@ncr-sd.SanDiego.NCR.COM> <1990009@hpctdls.HP.COM> <4009@brunix.UUCP> <282@calmasd.Prime.COM> Organization: Object Design Inc., Burlington, MA Lines: 49 In-reply-to: wlp@calmasd.Prime.COM's message of 14 Apr 89 15:45:22 GMT > There are also some very practical reasons for not using friends. > What do you do if (I should say *WHEN*) the definition of the object > class in question changes? How many files do you have to search > through to find the direct field accesses? Easy. The friends are all explicitly mentioned in the class declaration, just as the function members are. Therefore, when the implementation of the class changes, you go to the class definition and use it to find the names of all the function members and all the friends. Then you check out each one, and update it as necessary. The key issue is that every friend must be mentioned explicitly in the class definition. If that requirement did not exist, I would agree with your criticisms. Because friends are mentioned explicitly, they are a lot like function members as far as control of scoping and firewalling against updates are concerned. In fact, friends solve some tough problems in object-oriented programming that are left unsolved by most o-o languages. Sometimes it is truly necessary to have a piece of code that is part of the implementation of two classes, and knows about the internals of each class. (You may never have run into this need, but it comes up frequently in larger, more advanced systems. I believe there are some good examples in the libg++ library.) In such a case, I find that usually the two classes are best considered to be "one module", in a sense; that is, they get maintained together as a unit, rather than independently. Obviously, you don't do things like this unless there is a good reason; but sometimes there really *is* a good reason. The multimethods of CLOS (and its antecedent, CommonLoops) are sort of the same thing, although scoping rules in CLOS are so different from those in C++ that it is somewhat hard to draw a close analogy. There is no attempt so solve the problem in Smalltalk-80; but Smalltalk-80 shies away from another important features needed by large, serious o-o programs, namely multiple inheritance, so perhaps it is just their policy. To the best of my knowledge, the friend feature is unique to C++; C++ has been particularly innovative in the area of name scoping, particularly the private/protected/public distinction, an idea that other o-o languages could learn from. Students in an introductory o-o programming course are highly unlikely to run into the need for functions that are friends of two classes. In fact, they are unlikely to need friends at all. If I were teaching such a course, I might indeed tell the students to never use the "friend" feature; not because it is a bad feature, but because it can confuse you if you are still learning basic o-o concepts. P.S. CLOS is the object-oriented part of the Draft ANSI Common Lisp language, based on CommonLoops and New Flavors.