Topic: PROPOSAL: Hidden private parts of classes


Author: je@unix.brighton.ac.uk (John English)
Date: 2 Nov 92 17:00:18 GMT
Raw View
sabroe@daimi.aau.dk (Morten Sabroe Mortensen) writes:
:         Lately I've coded a lot of small libraries in C++, and been
: thinking, why it's not possible to hide private parts, -it doesn't
: seem to be possible!
: [... stuff deleted ...]
:         Now, from the point of view of the programmer, who uses
: "private.h", why in the world should he see the private part of the
: class A? The private part is part of the implementation, and therefore
: a distraction! It's a lose of abstraction!

Unfortunately, the compiler needs to know the size of an object to be
able to allocate storage for it, so it must see a complete declaration
before the first use. However, you can get around it (with a slight
loss of efficiency) by:

 struct data; // forward declaration

 class X {
 private:
  data* private_data;
 public:
  ...
 };

the point being that the compiler knows how big a pointer is, even if
it doesn't know what it points to.  You can have the declaration of `data'
in the .cpp file rather than the .h -- the only drawback is that all
data has to be referred to by `private_data->field'. The extra indirection
is probably a price worth paying IMHO.
--
-------------------------------------------------------------------------------
John English   | "Yes, understanding today's complex world of
Dept. of Computing  |  the future IS a little like having bees live
Brighton Polytechnic  |  in your head... but, there they are..."
Janet: je @ uk.ac.brighton.unix | "People who live in windowed environments
Fax:   0273 642405  |  shouldn't cast pointers"
-------------------------------------------------------------------------------




Author: frank@Cookie.secapl.com (Frank Adams)
Date: Wed, 04 Nov 1992 20:31:27 GMT
Raw View
In article <1csnjaINNqa0@hpsdlss3.sdd.hp.com> mark@sdd.hp.com (Mark Overton) writes:
>Morten Sabroe Mortensen writes:
>|>         Lately I've coded a lot of small libraries in C++, and been
>|> thinking, why it's not possible to hide private parts, -it doesn't
>|> seem to be possible!
>
>I asked this same question a couple of weeks ago in this newsgroup, and got
>basically two answers:
>
>   1. In the class declaration, declare a pointer to your private stuff.
>      Problem: you have to de-reference the pointer for each variable-use.
>
>   2. Add your private data in a subclass, and use virtual functions.
>      The users only need to see the base class, containing only public stuff.
>      Problem: every function-call is indirect (thru a pointer).

Another possible solution in some cases is to put the private stuff in a
separate include file, which is explicitly included by the "public" include
file:

class foo
{
#include"foo.prv"
    public:
    ...
}

This only deals with the "aesthetic" aspects of the problem.  Your users
will still have to recompile when you change your class definitions, and you
can't keep them from looking at the private source if they really want to.
But it does mean that the public include file will contain essentially only
the public class specification.




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: Sat, 7 Nov 1992 15:52:48 GMT
Raw View
In article <klamer.720538594@mi.el.utwente.nl> klamer@mi.el.utwente.nl (Klamer Schutte) writes:
>]But such knowledge is not necessary; the LINKER can decide the layout of
>]data in memory!  But alas, that would require new smarter linkers, and
>]then you couldn't use a cfront compiler.
>
>OK, that holds for global / static variables. But how for auto variables?
>These generally are efficient to use, but to be efficient, their size
>must be known at compile time.

 Why? Why cant the size be calculated by a smart linker
at link time? Why cant assembly output be made by the compiler
with 'sizeof_someobject' as a symbol yet to be determined?

>and thus can only a pointer to an object on the heap be used.

 NO, and I have SEEN it done otherwise in a Modula compiler,
I used it and it worked.

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: Sat, 7 Nov 1992 15:46:13 GMT
Raw View
In article <klamer.720475994@mi.el.utwente.nl> klamer@mi.el.utwente.nl (Klamer Schutte) writes:
>In <1992Oct30.113234.15010@daimi.aau.dk> sabroe@daimi.aau.dk (Morten Sabroe Mortensen) writes:
>
>>        Lately I've coded a lot of small libraries in C++, and been
>>thinking, why it's not possible to hide private parts, -it doesn't

>The compiler does not know what the data layout will be of the object.
>So the best he can do, is make a reference to the actual data.
>
>This means that the actual class will be just a pointer to the real data:

 No, when USING the interface the compiler doesnt need to
know about the private parts, it needs to know only the size of
the object to allocate storage for it.

 This can be done using external reference to the size,
or as I have seen done in a Modula compiler in which the
implementation has been compiler, the compiler looks up the
last size, uses that, and if it gets changed automatically
recompiles the module. This requires environment support that
C++ doesnt have though, but it can be done---without pointers.


--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: Sat, 7 Nov 1992 15:41:37 GMT
Raw View
In article <1992Oct30.113234.15010@daimi.aau.dk> sabroe@daimi.aau.dk (Morten Sabroe Mortensen) writes:
>        Lately I've coded a lot of small libraries in C++, and been
>thinking, why it's not possible to hide private parts, -it doesn't
>seem to be possible!


 You will note that 'private' means inaccessible to the public,
not invisible. It was explicitly defined that way in the ARM.

 Having hidden data variables causes the compiler some minor
inconvenience, not knowing the length. However private non-virtual
member functions cause no problems (if they were allowed). These are
IMHO needed so as to be able to write small helper members in
the implementation, I've suggested this be allowed, a suitable
syntax does not suggest itself though.

 Having an explict 'hidden' keyword could also be done:

 class A { ..
 hidden: int x;
 };

where x is not just inaccessible but invisible. (But not to the programmer)

 However there IS a way to separate the implementation and
the interface, namely to use an abstract class for the interface

 class X { public: f(); };
 class Y : public X { public: f(); private: int x;};

This makes x truly invisible to users of X objects, but not those
that must construct them. Note that this scheme will fail
if downcasting is allowed :-)

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: steve@taumet.com (Steve Clamage)
Date: Mon, 9 Nov 1992 03:22:25 GMT
Raw View
maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:

> Having hidden data variables causes the compiler some minor
>inconvenience, not knowing the length. However private non-virtual
>member functions cause no problems (if they were allowed). These are
>IMHO needed so as to be able to write small helper members in
>the implementation, I've suggested this be allowed, a suitable
>syntax does not suggest itself though.

If you mean private non-virtual member functions which don't appear in
the class definition, it would cause another language change.
Overloading is resolved before accessibility is checked.  Suppose we have:

 class X {
     foo(double); // private
 public:
     foo(int);
 };
 void bar()
 {
     X x;
     x.foo(2.0);  // which foo() ?
 }

This code is in error, since the best match is a private function.  The
semantics would change if "foo(double)" did not have to appear in the
publicly-used class definition; "foo(int)" would be called.  Overloading
is resolved first precisely to avoid quiet semantic changes based only
on access rights.
--

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16




Author: bill@amber.csd.harris.com (Bill Leonard)
Date: 9 Nov 92 19:32:55 GMT
Raw View
In article <klamer.721303355@mi.el.utwente.nl>, klamer@mi.el.utwente.nl (Klamer Schutte) writes:
>
> I doubt it. I can't see how a compiler can build a stack frame with
> auto variables, if the sizes of the elements on the stack frame are
> unknown. What can be done, is putting a pointer to the actual data in
> the stack frame, and allocate the data element itself on some heap
> (preferably a fast one, like alloca()).
>
> Otherwise the offsets of individual elements in the stack frame are unknown
> at compile time. These might be patched back at link time. (seems dirty
> to me). Allowing this you might loose some optimization opportunities.

Why do stack frames have to be fixed size?  Many languages, including Ada,
allow for automatic objects whose size is determined at runtime.  This is
not new technology, nor even all that hard.  In most implementations, the
compiler allocates a fixed-size part of the frame for its own use (like
register saving and such), plus all the known-sized automatic objects.  It
then computes the amount of space needed for variable-sized objects and
extends the stack frame by that amount.

In some languages, like Ada for instance, variable-sized objects can even
be declared in nested blocks and/or returned from functions!  This means
that the stack frame must grow and shrink as the function executes.  That
gets a little more complicated, but again, the technology is not new.

I think the clever thing to do for C++ would be to make the sizeof operator
be specifiable by the user, with arguments specified after the constructor
arguments, say.  For instance:

    Foo   * x = new Foo(/* constructor args */) (/* sizeof args */) ;

The built-in sizeof operator would automatically generate a function if the
size of the object is not known at compile-time.  This would necessitate,
of course, some way to indicate that you wanted to defer the complete
specification of the class in its declaration, and also some way to
complete that specification elsewhere.

As much as I would like to see this feature, though, I wouldn't argue for
its inclusion in the current standard.  Defer it until the next revision,
perhaps.  The standard has dragged on long enough -- it certainly has
enough in it to be useful (as evidenced by the large number of C++ users
already).

--
Bill Leonard
Harris Computer Systems Division
2101 W. Cypress Creek Road
Fort Lauderdale, FL  33309
bill@ssd.csd.harris.com
---------------------------------------------------------------------------
Prism: A place for light waves that commit minor refractions.
---------------------------------------------------------------------------




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: Tue, 10 Nov 1992 01:19:38 GMT
Raw View
In article <1992Nov9.032225.10320@taumet.com> steve@taumet.com (Steve Clamage) writes:
>maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
>
>> Having hidden data variables causes the compiler some minor
>>inconvenience, not knowing the length. However private non-virtual
>>member functions cause no problems (if they were allowed). These are
>>IMHO needed so as to be able to write small helper members in
>>the implementation, I've suggested this be allowed, a suitable
>>syntax does not suggest itself though.
>
>If you mean private non-virtual member functions which don't appear in
>the class definition, it would cause another language change.

 Yes, I propose ad additional keyword 'hidden' as well.
Hidden is like private, but is truly invisible not just inaccessible.
Static and non-virtual hidden functions can be defined without
declaring them in the clas interface, data must be declared in the
interface (but is still not visible outside the class).

>Overloading is resolved before accessibility is checked.  Suppose we have:
>
> class X {
>     foo(double); // private
> public:
>     foo(int);
> };
> void bar()
> {
>     X x;
>     x.foo(2.0);  // which foo() ?
> }
>
>This code is in error, since the best match is a private function.  The
>semantics would change if "foo(double)" did not have to appear in the
>publicly-used class definition; "foo(int)" would be called.  Overloading
>is resolved first precisely to avoid quiet semantic changes based only
>on access rights.

 I know. I do not propose to change 'private', but only add 'hidden'.
It would even be possible to have two different definitions of hidden
functions in different modules (thought perhaps not desirable).
Similar calls in private functions and public ones might resolve
differently, which is not nice, but neither the deriver nor the public
will need to cope with this, only the programmer of the class
implementation.

 In anycase there are several situations where one might
desire something like hidden functions. Often I am implementing
a class and need a helper member, I do not want this arbitrary
part of the implementation to be visible or cause recompilation
of client modules. Such helpers are particularly needed in C++
which does not allow nested functions. It is possible to write
non-member static helper functions, but not members.

 Perhaps there is a better way to do it.

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: sakkinen@jyu.fi (Markku Sakkinen)
Date: Tue, 10 Nov 1992 07:11:10 GMT
Raw View
In article <1992Nov9.032225.10320@taumet.com> steve@taumet.com (Steve Clamage) writes:
>maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
>> ...
>
>If you mean private non-virtual member functions which don't appear in
>the class definition, it would cause another language change.
>Overloading is resolved before accessibility is checked.  Suppose we have:
> ...
> ...  Overloading
>is resolved first precisely to avoid quiet semantic changes based only
>on access rights.

In my opinion, it was a bad choice in the first place to resolve
overloading before accessibility, although the argument presented in the ARM
makes partial sense.  However, that argument does not apply at all
to this new suggestion:  since such helper functions were to be declared
outside the class definitions, they cannot be made accessible to derived
classes or outside cliennt just by changing access rights.

----------------------------------------------------------------------
Markku Sakkinen (sakkinen@jytko.jyu.fi)
       SAKKINEN@FINJYU.bitnet (alternative network address)
Department of Computer Science and Information Systems
University of Jyvaskyla (a's with umlauts)
PL 35
SF-40351 Jyvaskyla (umlauts again)
Finland
----------------------------------------------------------------------




Author: steve@taumet.com (Steve Clamage)
Date: Tue, 10 Nov 1992 19:17:40 GMT
Raw View
sakkinen@jyu.fi (Markku Sakkinen) writes:

>In article <1992Nov9.032225.10320@taumet.com> steve@taumet.com (Steve Clamage) writes:
>>If you mean private non-virtual member functions which don't appear in
>>the class definition, it would cause another language change.
>>Overloading is resolved before accessibility is checked.  Suppose we have:
>> ...  Overloading
>>is resolved first precisely to avoid quiet semantic changes based only
>>on access rights.

>In my opinion, it was a bad choice in the first place to resolve
>overloading before accessibility, although the argument presented in the ARM
>makes partial sense.  However, that argument does not apply at all
>to this new suggestion:  since such helper functions were to be declared
>outside the class definitions, they cannot be made accessible to derived
>classes or outside cliennt just by changing access rights.

I neglected to carry my discussion to the next logical step.

The class could have different semantics depending on which declarations
were visible in which compilation units.  This is just what is being
asked for, but IMHO you should not want this facility; it is a
recipe for subtle bugs.

At the time you set up the class and provided some hidden functions
you had some reason for wanting to do so.  Maybe you even documented
it in a comment somewhere.  What about the next programmer doing
maintenance (which could be you 6 months later)?  Just what are the
slippery semantics of the class supposed to be?

Clients using the class expect precisely the visible semantics.  Some
impelemtation details depend on bent semantics.  When some of these
details need to be modified, which version of bent semantics should
be used?  What if the maintainer doesn't notice extra functions which
affect overloading but which are not visible in the class definition
and documentation?

Some languages (Modula, Ada) provide for completely hidden
implementation details.  This is a nice feature overall, but is
controlled in these languages.  I don't believe such languages
allow completely free and ad-hoc declarations, and it seems to
me that is what is being proposed here.
--

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: Wed, 11 Nov 1992 18:15:20 GMT
Raw View
In article <klamer.721303355@mi.el.utwente.nl> klamer@mi.el.utwente.nl (Klamer Schutte) writes:
>In <1992Nov7.155248.23401@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
>
>]In article <klamer.720538594@mi.el.utwente.nl> klamer@mi.el.utwente.nl (Klamer Schutte) writes:
>
>]>OK, that holds for global / static variables. But how for auto variables?
>]>These generally are efficient to use, but to be efficient, their size
>]>must be known at compile time.
>
>] Why? Why cant the size be calculated by a smart linker
>]at link time? Why cant assembly output be made by the compiler
>]with 'sizeof_someobject' as a symbol yet to be determined?
>
>]>and thus can only a pointer to an object on the heap be used.
>
>] NO, and I have SEEN it done otherwise in a Modula compiler,
>]I used it and it worked.
>
>I doubt it. I can't see how a compiler can build a stack frame with
>auto variables, if the sizes of the elements on the stack frame are
>unknown.

 The Modula compiler looks up the last definition of the type
and uses the size of that. If subsequently the system finds that
its been changed, auto-dependency checking causes the module
to be re-compiled.

 As I said before this requires environment support to
work, and is unlikely to be workable for C++ which doesnt have
the ability to pre-compile a class interface declaration.
Modula has separate INTERFACE and IMPLEMENTATION sections
for modules and it is possible to do this. Modula *requires*
environment support because it has a USE MODULENAME statment,
whereas C has #include filename. Modula has to associate
the internal MODULENAME with an external file containing
the precompiled module interface anyhow.

 So thats how it works. It was done deliberately to
avoid using a pointer on the stack.



--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: mccauleyba@vax1.bham.ac.uk (Brian McCauley)
Date: 30 Oct 92 19:06:57 GMT
Raw View
In article <1992Oct30.113234.15010@daimi.aau.dk>, sabroe@daimi.aau.dk (Morten Sabroe Mortensen) writes:
>         Lately I've coded a lot of small libraries in C++, and been
> thinking, why it's not possible to hide private parts, -it doesn't
> seem to be possible! Let me take a small example: I want to create
> a library, that is, a single header-file with some declarations to
> be used by anyone, and the implementation hidden in a .cc-file,
> -meant not to be seen by the one, who uses the declarations from the
> header-file. Nothing unusual with that....
>                                 ...This kind of hidden private parts
> would indeed come in handy, even though a few restrictions might be
> necessary to implement this kind of thing in current C++-compilers!
> For really large programs I belive it would matter a great deal!

Just a few restrictions... like not being able to have any objects of the type
as the compiler wouldn't know the size. inline functions would also be a
problem. Some compilers get round the problem of recompiling headers by
having `precompiled headers' which are to header files what object files are to
code files. If your concern is that you wan't to prevent programmers seeing
your privates then you'd also need to prevent them seeing the compiler's map
files. If your concern was the conpiler overhead - get a smarter compiler.

    \\   ( )  NO BULLSHIT! from BAM (Brian McCauley)
 .  _\\__[oo  ============
.__/  \\ /\@
.  l___\\     E-mail: B.A.McCauley@bham.ac.uk
 # ll  l\\
###LL  LL\\




Author: twbrown@PE-Nelson.COM (Tom W. Brown)
Date: 30 Oct 92 22:20:16 GMT
Raw View
In article <1992Oct30.113234.15010@daimi.aau.dk>, sabroe@daimi.aau.dk (Morten Sabroe Mortensen) writes:
|>
|>         Lately I've coded a lot of small libraries in C++, and been
|> thinking, why it's not possible to hide private parts, -it doesn't
|> seem to be possible!
|>
|> [example elided]
|>
|> -nothing is referenced before used, it seems! My thought is, that both
|> pair of files should result in the exact same code, when compiled!

No -- a problem (most likely not the only nor even the biggest problem) is
that the compiler can't compute the correct size of the object when it
doesn't have the full class definition.  Image the havoc wreaked when you
allocate an 'A' object from your application and the constructor proceeds
to access memory beyond the bounds of the allocated memory.

One solution is to store all private data in an "opaque" datatype and keep
only a pointer to this in the class; e.g:

   struct ADATA;      // This will be defined in a private header file

   class A {
   public:
      A();
      void print();
      .
      .
      .

   private:
      ADATA* data;    // We don't have to know the structure to declare a
   };                 // pointer to it.

Beyond hiding this information from applications that don't have to know
about the internals, this approach has the advantage of allowing you to
significantly change the internal data without requiring a recompilation of
all dependent applications since the size of an A will always stay the same!


----------------------------------------------------------------------------
Tom Brown               |  "Strange women, lying in ponds, distributing
PE Nelson Systems       |   swords is no basis for a system of government."
twbrown@pe-nelson.com   |                    Monty Python and the Holy Grail
----------------------------------------------------------------------------




Author: mark@sdd.hp.com (Mark Overton)
Date: 31 Oct 1992 01:30:18 GMT
Raw View
Morten Sabroe Mortensen writes:
|>         Lately I've coded a lot of small libraries in C++, and been
|> thinking, why it's not possible to hide private parts, -it doesn't
|> seem to be possible!

You are right, this is a serious defect in the C++ language.
It's a direct violation of the principle of information-hiding.

As prior responses have shown, the purpose of having private and public
stuff together is so the compiler will know the size of a non-dynamically
allocated object.
But such knowledge is not necessary; the LINKER can decide the layout of
data in memory!  But alas, that would require new smarter linkers, and
then you couldn't use a cfront compiler.

C++ traps us into the limitations of 60's linker technology, where linkers
merely linked.

I asked this same question a couple of weeks ago in this newsgroup, and got
basically two answers:

   1. In the class declaration, declare a pointer to your private stuff.
      Problem: you have to de-reference the pointer for each variable-use.

   2. Add your private data in a subclass, and use virtual functions.
      The users only need to see the base class, containing only public stuff.
      Problem: every function-call is indirect (thru a pointer).

Like this American presidential election, there are no good choices, so
one must select the least bad one.
I used solution #2.
  _________________________________________________________________________
 |                                                                         |
 | Mark Overton,  Hewlett-Packard (San Diego Div),  mark@sdd.hp.com        |
 |_________________________________________________________________________|




Author: davidm@consilium.com (David S. Masterson)
Date: 30 Oct 92 18:50:04 GMT
Raw View
The obvious problem with your proposal for hiding the private parts of objects
is that code compiled against only the public part of a class has no idea what
the size of the class is, so has no way of properly allocating stack space for
it when it is constructed.  For instance:

/* public part */
class A {
public:
 A();
};
/*****eof******/
#include "a_public.h"
int main() {
 A a; // how big is 'a'?
/*****eof******/
--
====================================================================
David Masterson     Consilium, Inc.
(415) 691-6311     640 Clyde Ct.
davidm@consilium.com    Mtn. View, CA  94043
====================================================================
  Speaking as a man, it's not a woman's issue.  Us men are tired
of losing our women
       -- Vice President Dan Quayle talking about
          breast cancer




Author: klamer@mi.el.utwente.nl (Klamer Schutte)
Date: Fri, 30 Oct 1992 20:13:14 GMT
Raw View
In <1992Oct30.113234.15010@daimi.aau.dk> sabroe@daimi.aau.dk (Morten Sabroe Mortensen) writes:

>        Lately I've coded a lot of small libraries in C++, and been
>thinking, why it's not possible to hide private parts, -it doesn't
>seem to be possible! Let me take a small example: I want to create
>a library, that is, a single header-file with some declarations to
>be used by anyone, and the implementation hidden in a .cc-file,
>-meant not to be seen by the one, who uses the declarations from the
>header-file. Nothing unusual with that. Look at the following two
>files:

 >> example deleted <<

Ok, now lets see how this will work out:
The compiler does not know what the data layout will be of the object.
So the best he can do, is make a reference to the actual data.

This means that the actual class will be just a pointer to the real data:

// public.h

class _A;

class A
{
public:
  void print();

private:
  class _A *private_data;
};

so here you have the class. This can be used by the user like this:

// public.cc

#include "public.h"

class A a;

void dummy()
{
 a.print();
}

On the implementation side you need to (re) define class A:

// private.h

#include "public.h"

class _A
{
 friend class A;

 int a;
};

And the actual implementation of the members of A must be given:

// private.cc

#include "private.h"
#include <iostream.h>

void
A::print()
{
 cout << private_data->a;
}

To be fair: idea borrowed from Interviews.

Klamer

--
Klamer Schutte   Tel: +31-53-892778 Fax: +31-53-340045
Faculty of electrical engineering -- University of Twente, The Netherlands
preferred: klamer@mi.el.utwente.nl     SMTP: klamer@utelmi01.el.utwente.nl




Author: klamer@mi.el.utwente.nl (Klamer Schutte)
Date: Sat, 31 Oct 1992 13:36:34 GMT
Raw View
In <1csnjaINNqa0@hpsdlss3.sdd.hp.com> mark@sdd.hp.com (Mark Overton) writes:

]Morten Sabroe Mortensen writes:
]|>         Lately I've coded a lot of small libraries in C++, and been
]|> thinking, why it's not possible to hide private parts, -it doesn't
]|> seem to be possible!

]You are right, this is a serious defect in the C++ language.
]It's a direct violation of the principle of information-hiding.

]As prior responses have shown, the purpose of having private and public
]stuff together is so the compiler will know the size of a non-dynamically
]allocated object.
]But such knowledge is not necessary; the LINKER can decide the layout of
]data in memory!  But alas, that would require new smarter linkers, and
]then you couldn't use a cfront compiler.

OK, that holds for global / static variables. But how for auto variables?
These generally are efficient to use, but to be efficient, their size
must be known at compile time. You specifically want to disallow this,
and thus can only a pointer to an object on the heap be used.

]I asked this same question a couple of weeks ago in this newsgroup, and got
]basically two answers:

]   1. In the class declaration, declare a pointer to your private stuff.
]      Problem: you have to de-reference the pointer for each variable-use.

Right! You don't know about the data members location, so you should
reference some kind of pointer!

]   2. Add your private data in a subclass, and use virtual functions.
]      The users only need to see the base class, containing only public stuff.
]      Problem: every function-call is indirect (thru a pointer).

Effectively you now use this as a pointer to your data.
And you disallow the use of auto variables, as your class should be an
abstract class. So you can use only pointers to not-global data.
Talking about indirectinf pointers...

]Like this American presidential election, there are no good choices, so
]one must select the least bad one.
]I used solution #2.

Am i glad that i am european ;-)

Klamer
--
Klamer Schutte   Tel: +31-53-892778 Fax: +31-53-340045
Faculty of electrical engineering -- University of Twente, The Netherlands
preferred: klamer@mi.el.utwente.nl     SMTP: klamer@utelmi01.el.utwente.nl




Author: acf@cs.unh.edu (Andrew C. Feren)
Date: 31 Oct 92 15:05:13
Raw View
A number of solutions have been offered for this all involving
pointers at some level.  Either a pointer to a private datatype or
using virtual functions and deriving a subclass that just inherits the
private members so that they are not seen by the user.

An other solution that was presented in a class on "object oriented
programming methodology" that I took is to include a file with the
private data.

Ex:
/*** FILE "public.h" ***********************************************/
class A
{
public:
  void print();

// note that it is a matter of style whether "private:" is actually
// here or at the top of "private.h"
private:
#include "private.h"
};

/*** eof "public.h" ************************************************/

/*** FILE "public.cc" **********************************************/

#include "public.h"

void A::print()
{ //...something!
}

/*** eof "public.cc" ***********************************************/

/*** FILE "private.h ***********************************************/

int a
// any other private information for class A

/*** eof "private.h" ***********************************************/


Since users are including private.h (albeit indirectly) they can still
see the information in it if they really want to.  Presumably,
however, since the information is private to the class and of no use
to the users of class A they will not go out of their way to look in
the file.  This method reduces the number of "distractions" in
public.h and avoids the need to use pointers if you really don't want
to.

cheers,
-Andrew Feren
 acf@kepler.unh.edu
 Cola@unh.edu