[comp.lang.c++] Can we hide the private part of a class ?

hsu@stratus (Yung-Kao Hsu) (09/07/88)

Hi, I am a new subscriber to this group and a semi-new user of GNU C++
(about 2 months). I am interested in learning whether it is possible to make
the private part of a class definition invisible ?

In Ada, a user-defined data structures can be made invisible by decalaring
their types as "private". While in Modula-2, you can do the same thing by
exporting the name of the type but not its definition. The data structures
are then declared in the body of the packages or implementation modules.
Besides the type information, these two languages also allow you to hide
the variables associated with the packages and definition modules.

This features make package/module interfaces cleaner (you don't see any
implementation information at all), and there are more advantages.
But, I couldn't find anything similiar in C++ !!

To make my question clearer, consider the following C++ class definition:

	class X { int x[10]; \\ private decalarations
		  public:
		  W,X, ...
		};

My question: is there anyway I can write this definition as:

	class X {
		public:
		W,X, ...
		};

while declaring "int x[10]" elsewhere (in separate file that is not
accessable by users of this class).

Can anyone answer me ?

Yung.
------

clive@drutx.ATT.COM (Clive Steward) (09/28/88)

From article <1358@stratus>, by hsu@stratus (Yung-Kao Hsu):
> 
> Hi, I am a new subscriber to this group and a semi-new user of GNU C++
> (about 2 months). I am interested in learning whether it is possible to make
> the private part of a class definition invisible ?
> 

It doesn't seem you can make anything truly invisible to the user of
a class without a customized preprocessor, because they're always going
to be able to read the header someplace if the compiler system can.

But one could probably simplify the 'user interface' by doing
something like:

in privatestuff.h:

#define FoosPrivates private:\
    int foo1; \
    char *foo2;		/* etc */

    /*
       be sure not to use any // C++ comments anywhere in this macro, as 
       C preprocessor won't understand them...
    */


then in your main header file for the class:

#include "privatestuff.h"

class foo {
    FoosPrivates;	// yes, the ; is unnecessary, but looks better?

public:

   // etc.

};

henry@utzoo.uucp (Henry Spencer) (09/29/88)

In article <1358@stratus> hsu@stratus (Yung-Kao Hsu) writes:
>This features make package/module interfaces cleaner (you don't see any
>implementation information at all), and there are more advantages.
>But, I couldn't find anything similiar in C++ !!

The reason is that these features hurt code efficiency.  The user does
not, in any case, get much benefit from seeing those implementation
details, because he can't make much use of them... but the compiler
can and does.  Consider your example:

>	class X { int x[10]; \\ private decalarations
>		  public:
>		  W,X, ...
>		};

The user can't access x, so seeing it won't do him much good.  However,
the compiler now knows exactly how big a variable of class X is, so it
can generate code that knows this.  If those private declarations were
hidden somewhere else, either the compiler has to get much more complex
or else class variables can't be as efficient as ordinary variables.
For example, as I recall (it's been a while...), since Modula 2 doesn't
tell the compiler how big the variable is, all the compiler can do for
space allocation is to allocate a pointer to the variable, and do all
accesses via that pointer.  This can be pretty slow.  The advantages
of the C++ method are even more prominent when you have something like:

	class foo {
		int x;
	public:
		int twice() { return 2*x; }
	} myvariable;

In C++, the code that results from using "twice" is essentially
"2 * myvariable.x"; note that there is no function call needed!  In
Modula 2, you can't do this without the full function-call overhead.

Remember, C++ is aimed primarily at the C community, which has a long
tradition of caring A LOT about efficiency.  There are many, many people
who are willing to adopt C++ only because they can be fairly sure that
they aren't losing significant efficiency by doing so.  C++, like C,
specializes in being fast rather than pretty.
-- 
The meek can have the Earth;    |    Henry Spencer at U of Toronto Zoology
the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu

shap@polya.Stanford.EDU (Jonathan S. Shapiro) (10/01/88)

In article <1988Sep29.044111.16104@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>In article <1358@stratus> hsu@stratus (Yung-Kao Hsu) writes:
>>This features make package/module interfaces cleaner (you don't see any
>>implementation information at all), and there are more advantages.
>>But, I couldn't find anything similiar in C++ !!
>
>The user can't access x, so seeing it won't do him much good.  However,
>the compiler now knows exactly how big a variable of class X is, so it
>can generate code that knows this.  If those private declarations were
>hidden somewhere else, either the compiler has to get much more complex
>or else class variables can't be as efficient as ordinary variables.
>For example, as I recall (it's been a while...), since Modula 2 doesn't
>tell the compiler how big the variable is, all the compiler can do for
>space allocation is to allocate a pointer to the variable, and do all
>accesses via that pointer.

All of what you say is true and good, and I think the tradeoff is
worth it, but it is worth pointing out on the other side that a
consequence of unifying the private and public parts of the code are
an increase in the header dependencies that can get explosive.
Consider having a private member of type froboz.  Even if there is no
public member of type froboz, all of the includers of the class
definition have to know what a froboz is - EVEN though they can't make
any use of the relevant member.

As someone who has developed large C++ systems, I have had occasion to
sadly regret this fact. On the other hand, I am more concerned with
the fact that there is NO way out of the run time cost in modula.

One technique that I have seen used to avoid this is to make all of
the private members part of a structure and declare the private part
as a structure reference. This is cumbersome to the coder, but in a
big system can be worth it.  Then when you have completed development
you make it an immediate object and insert a #include in the class def
header file.

The flip side of this is that what you say about both languages is
wrong given a good librarian.  The librarian could maintain the
component sizes, and at least for the client functions that would
eliminate unneeded dependency in both languages, subject to the
constraint that the private part be compiled first.

Jon

henry@utzoo.uucp (Henry Spencer) (10/02/88)

In article <4193@polya.Stanford.EDU> shap@polya.Stanford.EDU (Jonathan S. Shapiro) writes:
>The flip side of this is that what you say about both languages is
>wrong given a good librarian.  The librarian could maintain the
>component sizes, and at least for the client functions that would
>eliminate unneeded dependency in both languages, subject to the
>constraint that the private part be compiled first.

Um, no, it doesn't eliminate the dependencies, it just hides them.  If
you change the size of something, everything that knows about it still
has to be recompiled.  It's essentially the equivalent of synthesizing
the *real* header file from a fake one (with no private information)
and the private part.

Remember, too, that sizes are the easy part -- things like inline functions
are both more significant and harder to do.
-- 
The meek can have the Earth;    |    Henry Spencer at U of Toronto Zoology
the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu

akwright@watdragon.waterloo.edu (Andrew K. Wright) (10/02/88)

In article <4193@polya.Stanford.EDU> shap@polya.Stanford.EDU (Jonathan S. Shapiro) writes:
>The flip side of this is that what you say about both languages is
>wrong given a good librarian.  The librarian could maintain the
>component sizes, and at least for the client functions that would
>eliminate unneeded dependency in both languages, subject to the
>constraint that the private part be compiled first.

A problem I see here is a stubborn adherence by many people to the
conventional C-like or Ada-like view of separate compilation.  Since
the public part of a class can be generated automatically from the
private part, why force the user to enter it at all?  The compilation
system (souped-up librarian) can determine it when compiling a program,
and a tool can be provided to produce it for a reader.  Eiffel is one
existing OO language which operates this way.  The research languages
I have been working on for several years all operate this way.
-- 
Andrew K. Wright      watmath!akwright
CS Dept., University of Waterloo.

hsu@cumulus (Yung-Kao Hsu) (10/03/88)

---------

In article <1988Sep29.044111.16104@utzoo.uucp> henry@utzoo.uucp
(Henry Spencer) writes:

>In article <1358@stratus> hsu@stratus (Yung-Kao Hsu) writes:
>>This features make package/module interfaces cleaner (you don't see any
>>implementation information at all), and there are more advantages.
>>But, I couldn't find anything similiar in C++ !!
>
>The user can't access x, so seeing it won't do him much good.  However,

This is true if all public functions won't return any pointer to x.
But, sometimes for efficiency reason, we will allow such bad pratice.

For example, if x is a table whose element is defined as an union of 5
different data types and there are 5 different classes that defined to
handle these data types. Since the main function for the object containing
x is record keeping, pointers seems to be the best choices for both efficiency
and program readability in designing the interfaces between these classes.

But, since we can see the definition and with pointers, nothing is safe.
Anyway, I agree that what you said in general is right.

In article <1988Sep29.044111.16104@utzoo.uucp> henry@utzoo.uucp
(Henry Spencer) continues:
>the compiler now knows exactly how big a variable of class X is, so it
>can generate code that knows this.  If those private declarations were
>hidden somewhere else, either the compiler has to get much more complex
>or else class variables can't be as efficient as ordinary variables.
>For example, as I recall (it's been a while...), since Modula 2 doesn't
>tell the compiler how big the variable is, all the compiler can do for
>space allocation is to allocate a pointer to the variable, and do all
>accesses via that pointer.

In article  <4193@polya.Stanford.EDU>  shap@polya.Stanford.EDU
(Jonathan S. Shapiro)replied:

: All of what you say is true and good, and I think the tradeoff is
: worth it, but it is worth pointing out on the other side that a
: consequence of unifying the private and public parts of the code are
: an increase in the header dependencies that can get explosive.
: Consider having a private member of type froboz.  Even if there is no
: public member of type froboz, all of the includers of the class
: definition have to know what a froboz is - EVEN though they can't make
: any use of the relevant member.

The problem Jon mentioned above was in fact the main reason for my initial
question. I have devloped a very simple compiler in G++ as a framework for
project assignment to be used in compiler course my advisor taught. But, I
simply couldn't write a proper makefile to make seperate compilation
possible. The header dependency simply forces re-compilation of all program
units if some private declarations were changed (which shouldn't cause any
problem to any other classes).

Even though Jon had a semi-solution to this problem, but I think it is
too human-intensive (for undergraduate students at least). Anyway, thanks
to both Jon and Henry for your information.

-- 
YUNG-KAO HSU
School Of Infomation & Computer Science, Georgia Tech Atlanta GA30332
Internet:  hsu@cumulus.gatech.edu	 CSNet:  hsu%cumulus@gatech	
UUCP:  ...!{akgua,allegra,amd,hplabs,seismo,ihnp4}!gatech!cumulus!hsu

ekrell@hector.UUCP (Eduardo Krell) (10/03/88)

In article <1368@cumulus> hsu@cumulus.UUCP (Yung-Kao Hsu) writes:

>The header dependency simply forces re-compilation of all program
>units if some private declarations were changed (which shouldn't cause any
>problem to any other classes).

You can't really say that. What if something like sizeof() was used?
Adding or removing private members from a class may change its size.
    
Eduardo Krell                   AT&T Bell Laboratories, Murray Hill, NJ

UUCP: {att,decvax,ucbvax}!ulysses!ekrell  Internet: ekrell@ulysses.att.com

shap@polya.Stanford.EDU (Jonathan S. Shapiro) (10/03/88)

In article <1368@cumulus> hsu@cumulus.UUCP (Yung-Kao Hsu) writes:
>---------
>
>In article <1988Sep29.044111.16104@utzoo.uucp> henry@utzoo.uucp
>(Henry Spencer) writes:
>
>>The user can't access x, so seeing it won't do him much good.  However,
>
>This is true if all public functions won't return any pointer to x.
>But, sometimes for efficiency reason, we will allow such bad pratice.

The fact that a programmer can willfully break the type system is not
a good argument here. I can also use integer pointers as character
pointers. If the function returning pointer wants to be type-safe,
it should be declared as returning a pointer to a class member. In
that case, what Henry says continues to be true.

Jon

hsu@cumulus (Yung-Kao Hsu) (10/03/88)

In article <10681@ulysses.homer.nj.att.com> ekrell@hector.UUCP (Eduardo Krell) writes:
>In article <1368@cumulus> hsu@cumulus.UUCP (Yung-Kao Hsu) writes:
>
>>The header dependency simply forces re-compilation of all program
>>units if some private declarations were changed (which shouldn't cause any
>>problem to any other classes).
>
>You can't really say that. What if something like sizeof() was used?
>Adding or removing private members from a class may change its size.
>    
>Eduardo Krell                   AT&T Bell Laboratories, Murray Hill, NJ
>
>UUCP: {att,decvax,ucbvax}!ulysses!ekrell  Internet: ekrell@ulysses.att.com

The problem you mentioned above really only hit half of the target. If the
sizeof() was used, the data type involved really is not private as far as
I can see. If you consider the example I mentioned in the posting,
i.e, an object that handles a table of values. The changes of table size
should not affect those object who use it, since they are only interested
in storing and retrieve data elements. But the changes of the table element
size should, since the data element type is part of interface specification.

But, C++ simply does not support any mechansim like ada and modula-2 that
help in distincting these situations. Thus, in most cases, you have to take
care of what should be recompiled and what needs not. I feel this is a very
serious problem if we want to use C++ in a large project or consider it as
an object-oriented language.

---------
-- 
YUNG-KAO HSU
School Of Infomation & Computer Science, Georgia Tech Atlanta GA30332
Internet:  hsu@cumulus.gatech.edu	 CSNet:  hsu%cumulus@gatech	
UUCP:  ...!{akgua,allegra,amd,hplabs,seismo,ihnp4}!gatech!cumulus!hsu

hsu@cumulus (Yung-Kao Hsu) (10/03/88)

In article <4223@polya.Stanford.EDU* shap@polya.Stanford.EDU
(Jonathan S. Shapiro) writes:

*In article <1368@cumulus> hsu@cumulus.UUCP (Yung-Kao Hsu) writes:
**
**In article <1988Sep29.044111.16104@utzoo.uucp* henry@utzoo.uucp
**(Henry Spencer) writes:
**
***The user can't access x, so seeing it won't do him much good.  However,
**
**This is true if all public functions won't return any pointer to x.
**But, sometimes for efficiency reason, we will allow such bad pratice.
*
*The fact that a programmer can willfully break the type system is not
*a good argument here. I can also use integer pointers as character
*pointers. If the function returning pointer wants to be type-safe,
*it should be declared as returning a pointer to a class member. In
*that case, what Henry says continues to be true.
*
*Jon

What I really should say in the previous posting is: the language should
provide some mechanisms (i.e, hiding the data type definition) that prevent
the programmer from mis-use even they want to.

Also, your example is not quite convincing, since character and integer
are not considered as "private" types but pre-defined public data types
and we all know how they are implemented.

-----
-- 
YUNG-KAO HSU
School Of Infomation & Computer Science, Georgia Tech Atlanta GA30332
Internet:  hsu@cumulus.gatech.edu	 CSNet:  hsu%cumulus@gatech	
UUCP:  ...!{akgua,allegra,amd,hplabs,seismo,ihnp4}!gatech!cumulus!hsu

david@june.cs.washington.edu (David Callahan) (10/04/88)

In article <1988Oct2.045604.17456@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>In article <4193@polya.Stanford.EDU> shap@polya.Stanford.EDU (Jonathan S. Shapiro) writes:
>>The flip side of this is that what you say about both languages is
>>wrong given a good librarian. ...
>
>Um, no, it doesn't eliminate the dependencies, it just hides them.  If
>you change the size of something, everything that knows about it still
>has to be recompiled. ...

Changing the size or position of private elements changes only the 
offsets of the public elements. These could be treated as external 
variables and bound at link time rather than compile time. There might
small performance penalty if a particular architecture handles small
offsets better than big ones and the compiler must assume a big offset.
This goes for sizeof() too.

>Remember, too, that sizes are the easy part -- things like inline functions
>are both more significant and harder to do.
>-- 
>The meek can have the Earth;    |    Henry Spencer at U of Toronto Zoology
>the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu

Inline functions are real compilation dependences and can not be hidden by late
binding, but the orginal poster's intent was to hide implementation details, 
not avoid recompilation when public information changes, 
and that is certainly posible.


David Callahan

ekrell@hector.UUCP (Eduardo Krell) (10/04/88)

In article <1369@cumulus> hsu@cumulus.UUCP (Yung-Kao Hsu) writes:

>The problem you mentioned above really only hit half of the target. If the
>sizeof() was used, the data type involved really is not private as far as
>I can see.

I didn't explain myself. I meant to say that anytime the size of the class
is needed (e.g., when you generate an instance of the class), that module
will have to be recompiled.

You don't have to use sizeof() directly, but the compiler will need it
to generate the right argument for malloc() when you create an object
of that class.

And there's more. You can move members around and add/remove private
members.  That could change the relative offsets of members in the
class. A program that was using object->member now needs to be
recompiled because the offset of "member" might have changed...
    
Eduardo Krell                   AT&T Bell Laboratories, Murray Hill, NJ

UUCP: {att,decvax,ucbvax}!ulysses!ekrell  Internet: ekrell@ulysses.att.com

ekrell@hector.UUCP (Eduardo Krell) (10/04/88)

In article <5922@june.cs.washington.edu> david@uw-june.UUCP (David Callahan) writes:

>Changing the size or position of private elements changes only the 
>offsets of the public elements. These could be treated as external 
>variables and bound at link time rather than compile time.

This is a bad idea as it would break all the C++ <-> C compatibility.
Imagine a C++ program calling stat() and then trying to access the
elements of the stat structure returned by the kernel ...
    
Eduardo Krell                   AT&T Bell Laboratories, Murray Hill, NJ

UUCP: {att,decvax,ucbvax}!ulysses!ekrell  Internet: ekrell@ulysses.att.com

robert@pvab.UUCP (Robert Claeson) (10/04/88)

In article <4193@polya.Stanford.EDU>, shap@polya.Stanford.EDU (Jonathan S. Shapiro) writes:

[discussion about how to hide the private part of a class declaration deleted]

> ... Then when you have completed development
> you make it an immediate object and insert a #include in the class def
> header file.

Sometime during this last winter, someone from Glockenspiel, Ireland, wrote
something on this subject in  this newsgroup (John Carolan, please step
forward). The article wasn't very long, but was well worth reading. I'm
afraid I have lost it.

And yes, his method included the use of a pointer.
-- 
Robert Claeson, ERBE DATA AB, P.O. Box 77, S-175 22 Jarfalla, Sweden
Tel: +46 758-202 50   Fax: +46 758-197 20
Email: robert@pvab.se (soon rclaeson@erbe.se)

ech@poseidon.UUCP (Edward C Horvath) (10/05/88)

Henry Spencer observes:
> Remember, C++ is aimed primarily at the C community, which has a long
> tradition of caring A LOT about efficiency.  There are many, many people
> who are willing to adopt C++ only because they can be fairly sure that
> they aren't losing significant efficiency by doing so.  C++, like C,
> specializes in being fast rather than pretty.

Deja vu.  In the mid-70s, Berk Tague (the first manager of the
Bell Labs Unix Support Group) said that he didn't really believe that
the choice of language was important.  However, C was the only language
he had found that would woo the diehards away from assembler.

I suppose I'm a diehard, too.  I suspect that stems from 20 years of
hearing the same argument that "the next generation of hardware will let
{LISP, SNOBOL, shell scripts, smalltalk, your language here} run fast
enough to obviate the efficiency issues."  And 20 years of seeing the
demands placed on the programs increase as fast as the hardware power.
And 20 years of seeing the efficiency freaks eat up the market share.
So I still code the innermost loops in assembler.

The reality is that each new level of abstraction in the programming
process has to prove itself ECONOMICALLY.  I hear the arguments about how
much more efficient object-oriented programming is, in terms of reuse of
code and better maintainability.  But if there's an efficiency penalty,
it's going to cost me market share EARLY, and maintainability is moot to
a company that's folded.  When a 5- or 10 year old software product team
reports the continuing evolutionary quality of their product, and the
reduced maintenance costs, without an efficiency penalty, everybody will
jump on the bandwagon (or already be beyond it).  But end-users just
can't see the internal cleanliness, although they've become better about
demanding timely updates and fast response to bug reports.

Bjarne Stroustroup clearly recognizes these issues.  The C++ book
apologizes, and properly so, for the "unclean" aspects of the language.
His apologia, however, almost invariably involve allowing the compiler
to do a better job of generating code.  The result is a compromise,
enlightened by the SmallTalk experience, but tempered by a recognition
of the reality "real" programmers face.  I'm switching to C++ just as
soon as I have a compiler for my Mac (maybe even when there's a
preprocessor, we'll see), because it looks like it will help me more
than it will cost me.  I'm not switching to SmallTalk, it just isn't
fast enough for production-quality applications.

Ultimately, I do believe that we'll program in an evolutionary fashion
that exploits the strengths of what-has-gone-before.  I have not been
persuaded that we know enough to construct that ultimate programming
environment.

But I've started reading about Eiffel...

=Ned Horvath=

chris@mimsy.UUCP (Chris Torek) (10/05/88)

-In article <4223@polya.Stanford.EDU* shap@polya.Stanford.EDU
-(Jonathan S. Shapiro) suggests that
->The fact that a programmer can willfully break the type system is not
->a good argument here. I can also use integer pointers as character
->pointers. If the function returning pointer wants to be type-safe,
->it should be declared as returning a pointer to a class member. In
->that case, what Henry says continues to be true.

In article <1375@cumulus> hsu@cumulus (Yung-Kao Hsu) answers:
-What I really should say in the previous posting is: the language should
-provide some mechanisms (i.e, hiding the data type definition) that prevent
-the programmer from mis-use even they want to.

It cannot be done.  If the programmer is curious enough, or desperate
enough, he will physically disassemble the machine in order to make it
do what he wants.  I know, for I have done it.  Far better than making
it hard to do it wrong is making it easy to do it right.

-Also, your example is not quite convincing, since character and integer
-are not considered as "private" types but pre-defined public data types
-and we all know how they are implemented.

Except that many people who `know' this are in fact wrong.  The analogy
seems reasonably apt to me.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

henry@utzoo.uucp (Henry Spencer) (10/06/88)

In article <5922@june.cs.washington.edu> david@uw-june.UUCP (David Callahan) writes:
>Changing the size or position of private elements changes only the 
>offsets of the public elements. These could be treated as external 
>variables and bound at link time rather than compile time. There might
>small performance penalty...

There will be a large performance penalty on many modern machines, unless
the linker is smart enough to practically redo the code generation to
compensate.  Things like limited-range offset addressing modes, which are
very common, really do require knowing the offset at code-generation time
to avoid having to generate much slower worst-case code.

>Inline functions are real compilation dependences and can not be hidden by late
>binding, but the orginal poster's intent was to hide implementation details, 
>not avoid recompilation when public information changes, 

Inline functions are an optimization; their contents are no more "public
information" than the types and sizes of private members.
-- 
The meek can have the Earth;    |    Henry Spencer at U of Toronto Zoology
the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu

jellinghaus-robert@CS.YALE.EDU (Rob Jellinghaus) (10/07/88)

In article <528@poseidon.UUCP> ech@poseidon.UUCP (XMRJ50000-Edward C Horvath;LZ 3F-315;3005) writes:
>Ultimately, I do believe that we'll program in an evolutionary fashion
>that exploits the strengths of what-has-gone-before.  I have not been
>persuaded that we know enough to construct that ultimate programming
>environment.
>
>But I've started reading about Eiffel...

I've heard it mentioned 3 times already, and this is the first time I've
ever read this newsgroup.  What is Eiffel?  Could someone supply some
references?

>=Ned Horvath=

Rob Jellinghaus                | "SINGAPORE?!?  You're supposed to be a
jellinghaus-robert@CS.Yale.EDU |  COWBOY!  What kind of cowboy song is
ROBERTJ@{yalecs,yalevm}.BITNET |  THAT??!!  Singapore, I oughta--"
{everyone}!decvax!yale!robertj |      -- Eddie Foy, _The Cowboy Wally Story_

halldors@paul.rutgers.edu (Magnus M Halldorsson) (10/07/88)

Eiffel is a OO prog lang, written by Bertrand Meyer, published by
Interactive Software Eng. Inc. It has multiple inheritance etc.
  Look at the new Journal of Object-Oriented Computing, issue#2 has a
review of it. Meyer also has a recent book out (1987) on OOP using
Eiffel. I can look it up if you can't find it.

Magnus

cmc@inf.rl.ac.uk (Chris Crampton) (11/21/88)

In article <322@pvab.UUCP> robert@pvab.UUCP (Robert Claeson) writes:
>In article <4193@polya.Stanford.EDU>, shap@polya.Stanford.EDU (Jonathan S. Shapiro) writes:
>
>[discussion about how to hide the private part of a class declaration deleted]
>
>> ... And yes, his method included the use of a pointer.

One solution I have used which really is quite straight forward and bound to
have occured to others is as follows:

------------foo.h------------------

class	foo
 {
	struct	foo_privates*	pfoo;	// private data
	
	void	private_method();
	...
public:
	...
 };

------------foo.c------------------

#include	"foo.h"

struct foo_privates
 {
	...	// implementation dependant data and methods
 };

 ...		// implementation code

-----------------------------------

The file foo.h is included by all users of the foo class and foo.c is the
implementation module for class foo. It is only in the latter that the
private data of foo is described, thus hiding any details. Only foo.h
need be distributed with the library providing the foo class.

If, of course, the parts of the implementation that need access to the
private data are spread across more than one C++ file then the private
data would have to be described in additional header file (which needn't
be distributed).

There are two advantages to this scheme:

	- the details of the implementation are kept private

	- if the implementation is changed but the interface remains
	  unchanged then the amount of recompilation necessary is
	  greatly reduced

There are disadvantages:

	- private methods become messy in that they aren't part of the
	  actual class or, if they are, then they are exposed in the header
	  file (as in private_method() above)

	- when debugging classes using debuggers intended for old C then
	  the private struct probably has to be moved into the header file
	  so that complete debugging can be performed

	- inline funcions which use private data are not possible

You pays yer money...

Chris.

=======================================================================
Chris M Crampton		JANET:	cmc@uk.ac.rl.inf
Informatics Department		ARPA:	cmc%inf.rl.ac.uk@nss.cs.ucl.ac.uk
Rutherford Appleton Labs,	UUCP:	..!mcvax!ukc!rlvd!cmc
Didcot, OXON, OX11 0QX, U.K.		cmc@rlvd.uucp
Tel. +44 235 44 6756
FAX. +44 235 44 5831