mgardi@watdcsu.waterloo.edu (M.Gardi - ICR) (06/20/89)
I am a little curious as to how one can completely remove implementation details of a C++ class from the user of the class. I would like to design a system that users need only know the public declarations and nothing else to use the class. It seems to me that I will always have to provide a Header file that contains at least the declarations of all my private information. Ultimately, I would like to give them a library containing my classes and NOTHING else. Could someone please clue me in! p.
jima@hplsla.HP.COM (Jim Adcock) (06/23/89)
> Ultimately, I would like to give them a library containing my classes and > NOTHING else. Why? Seems like letting people see a little bit of your class might be a good thing. I find it very comforting to be able to look at complex.h for example. Reading it, I get the impression that the person writing it might very well know what they're doing. Yet not enough is given away that I could /cause/get into/ any trouble. In any case, I hope you meant to say that you would like to at least give them a manual page explaining how to use your class along with the library. Software without good documentation isn't reusable.
diamond@diamond.csl.sony.junet (Norman Diamond) (06/26/89)
Some poster (attribution previously deleted) writes: >> Ultimately, I would like to give them a library containing my classes and >> NOTHING else. In article <6590164@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: >I find it very comforting to be able to look at complex.h for >example. Reading it, I get the impression that the person writing it might >very well know what they're doing. Have you looked at your C compiler? I still use C compilers and they usually work. But after seeing two of them, I get the impression that the people writing them did not know what they were doing. In some cases, they did not even know the C language. If a program works, has been reviewed/benchmarked/whatever, maybe you're better off accepting it without looking at its source code. -- Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.jp@relay.cs.net) The above opinions are claimed by your machine's init process (pid 1), after being disowned and orphaned. However, if you see this at Waterloo, Stanford, or Anterior, then their administrators must have approved of these opinions.
nevin1@cbnewsc.ATT.COM (nevin.j.liber) (06/26/89)
In article <6590164@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: |Someone else wrote: |> Ultimately, I would like to give them a library containing my classes and |> NOTHING else. |Why? Seems like letting people see a little bit of your class might be a |good thing. I find it very comforting to be able to look at complex.h for |example. Reading it, I get the impression that the person writing it might |very well know what they're doing. Yet not enough is given away that I |could /cause/get into/ any trouble. Maybe, maybe not. Programmers are clever people :-); they tend to use ALL the information they are given. From the header file one might guess on how the class is implemented, find some undocumented side effects, and write code that uses these side effects. This breaks the clean interface which classes provide, and leads to many of the "existing practice" problems which can be found throughout pANS C. I'd much rather have all the implementation details for a class hidden from me. -- NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751
solomon@gjetost.cs.wisc.edu (Marvin Solomon) (06/27/89)
There's been some discussion about why the .h file describing a class
needs to include information about the private part of the class, and
whether that's a good thing. I remember when I first read about Ada,
I found it strange that a package *specification* contained information
about the hidden parts of the package. On reflection, I figured out
the justification. It's simple once you see it, but perhaps not obvious,
especially to those who are not compiler experts.
The trouble is that a class definition serves two purposes: to document
the class interface to a human user and to provide a compiler with enough
information to compile a client of the class. The private members are
superfluous (indeed, it could be argued they are harmful) for the former
purpose, but essential for the latter. Consider:
someclass.h:
class SomeClass {
public:
int visible;
private:
char hidden[10];
};
client.c:
#include "someclass.h"
Someclass arr[15];
...
arr[1].visible = 17; // movl #17,arr+16, assuming fullword alignment
To compile client.c, the compiler needs to know the size of a SomeClass.
I can think of no straightforward implementation-independent way of
conveying this information other than to include the "private" section
in someclass.h. The C++ language goes to some pains to ensure that the
client programmer can't "use" the extra info. For example
cout << arr[1].hidden;
is an error. But a sufficiently "clever" hacker might *abuse* the information:
printf("%s",&(arr[1].visible)+1);
Such programmers get what they deserve.
--
Marvin Solomon
Computer Sciences Department
University of Wisconsin, Madison WI
solomon@cs.wisc.edu, ...seismo!uwvax!solomonrichard@pantor.UUCP (Richard Sargent) (06/29/89)
Regarding the question of C++ header files containing the public and private information both, the information *has* to be there for the compiler. However, you can alleviate the problems caused by extracting only the public portions and publishing those as adjunct to man pages or whatever. This can be fairly automated via judicious use of "#if !defined(EXTRACT)" directives throughout and use 'make' and the preprocessor to fairly automatically extract the public portions. Of course, you can write your own utilities to do whatever you want ... Naturally, this does not solve the 'problem' of someone attempting to learn more about a class than they should, but I doubt anything will, short of a completely closed and regulated programming/development environment (and you thought editor wars were extreme!). It will, however, allow people to easily learn what they do need to know without 'burdening' them with the stuff they shouldn't know. As with everything involving C/C++, it all comes down to discipline in the end. Richard Sargent Internet: richard@pantor.UUCP Systems Analyst UUCP: uunet!pantor!richard
db@lfcs.ed.ac.uk (Dave Berry) (06/30/89)
In article <7709@spool.cs.wisc.edu> solomon@gjetost.cs.wisc.edu (Marvin Solomon) writes: > [An explanation of why class definitions must include private members, > so that the compiler knows the size of the class.] This doesn't explain why private function members must be included. It's a real pain to have to recompile a large part of a program just because you've added a private function to do some internal processing. Of course you could write the function at the top level and make it take the relevant object as an argument, but this defeats some of the purpose of using classes. I'd like to be able to define private member functions outside the class, e.g. private Result* Foo::foo (Bar*, Stool*); Then only the changed .c file would need to be recompiled. Other approaches to this would be to use a separate header file to store the private member functions, and to write your makefile so that only the relevant .c file was recompiled when the private .h file was changed. Unfortunately this wouldn't work with makedepend, which I use a lot. There are several ways that a C++ environment could handle this neatly, providing the facilities of both make and makedepend, but allowing private functions to be defined outside the class would be more portable. Dave Berry, Laboratory for Foundations db%lfcs.ed.ac.uk@nsfnet-relay.ac.uk of Computer Science, Edinburgh Uni. <Atlantic Ocean>!mcvax!ukc!lfcs!db "It's not a good omen when goldfish commit suicide."
pcg@aber-cs.UUCP (Piercarlo Grandi) (06/30/89)
In article <2465@etive.ed.ac.uk> db@lfcs.ed.ac.uk (Dave Berry) writes: In article <7709@spool.cs.wisc.edu> solomon@gjetost.cs.wisc.edu (Marvin Solomon) writes: > [An explanation of why class definitions must include private members, > so that the compiler knows the size of the class.] This doesn't explain why private function members must be included. It's a real pain to have to recompile a large part of a program just because you've added a private function to do some internal processing. [ ... ] Other approaches to this would be to use a separate header file to store the private member functions, and to write your makefile so that only the relevant .c file was recompiled when the private .h file was changed. Let me insist that an import/export facility with compiled headers would be the ideal solution... And it is fairly easy to implement. And one could still use #include for backwards compatibility. And ... (whining again on this subject :->) -- Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
strange@cbnewsl.ATT.COM (philip.e.brown) (06/30/89)
There is still some discussion about this, so I'll pass along the mail I sent to the original poster. (Subsequent articles have covered some of this already.) /////////////////////////////////////////////////////// In article <6031@watdcsu.waterloo.edu> you write: > >I am a little curious as to how one can completely remove implementation >details of a C++ class from the user of the class. >I would like to design a system that users need only know the public >declarations and nothing else to use the class. >It seems to me that I will always have to provide a Header file that >contains at least the declarations of all my private information. >Ultimately, I would like to give them a library containing my classes and >NOTHING else. >Could someone please clue me in! As with everything else, there is a cost for complete information hiding. The cost here is the added level of indirection necessary to defer implementation details. My suggestion is to try something like: ////////////// // header file class hide1; // classes for hidden implementation ... class hideN; class interface { hide1 *hidden1; // handle into implementation ... hideN *hiddenN; public: interface_func1(); // can't define yet ... interface_funcM(); }; // end header file ////////////////// ////////////// // source file class hide1 { /* implementation details */ }; ... class hideN { /* implementation details */ }; interface::interface_func1() { /* implementation details */ } ... interface::interface_funcM() { /* implementation details */ } // end source file ////////////////// The header file contains only the information necessary for the interface. All else is hidden. An additional benefit is that recompilation is only necessary when the interface has changed. When just the implementation has been updated, only the files containing the implementation are affected. Phil Brown AT&T Bell Labs attunix!strange
grunwald@flute.cs.uiuc.edu (Dirk Grunwald) (08/08/89)
there is no reason why information hiding should require more indirection; it only requires a good compiler. however, C++ was designed in the good-ol' UNIX programing environment where there's no intermediate files other than .o files and all compilers read source files. That's why inlines have to be visible. -- Dirk Grunwald -- Univ. of Illinois (grunwald@flute.cs.uiuc.edu)