Topic: [proposal] Accessing private members in objects of a derived class


Author: barmar@think.com (Barry Margolin)
Date: 16 May 1994 16:06:31 GMT
Raw View
In article <2989@ulogic.UUCP> hartman@ulogic.COM writes:
>Hey, we're both instances of the class "Human", but I don't want
>YOU fiddleing with MY private parts! <g>

When two humans are having sex, each is expected to fiddle with each
other's private parts.

(I've also found that the sex analogy is good for explaining the value of
multi-methods.)
--
Barry Margolin
System Manager, Thinking Machines Corp.

barmar@think.com          {uunet,harvard}!think!barmar




Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 12 May 1994 03:05:09 GMT
Raw View
>>>>> Richard M Hartman <hartman@ulogic.UUCP> writes:

> In other words -- I think that "private" should be private to the
> instance, not the class

Some OOPLs work that way; Bjarne decided that C++ would work on a class
by class basis.  See section 11.2c of the ARM for more information.

> and especially not it's descendants.

C++ already denies descendants access to private members.

Jason




Author: guthrie@miu.edu
Date: Wed, 11 May 94 21:52:15 CDT
Raw View
In article <2989@ulogic.UUCP>, <hartman@ulogic.UUCP> writes:
> From: hartman@ulogic.UUCP (Richard M. Hartman)
> Newsgroups: comp.std.c++,comp.lang.c++
> Subject: Re: [proposal]  Accessing private members in objects of a derived
class
> Followup-To: comp.std.c++
> In other words -- I think that "private" should be private to the
> instance, not the class and especially not it's descendants.
> .... on the other hand, with the SCO development system, the example
> you provided works just fine <g>
I don't think think the ARM agrees with you on #1, (microsoft too)
  but does on #2. (me too!)
Two points:
1) The original message was not about others accessing private members,
   but about Base member functions; the issue was not _if_ member
   functions should have access to private members of their own class,
   but the issue of how they get access...
   Note that if one did a cast of Der -> base (perfectly valid),
   then the access would be OK..

2) The proposal for change, was the same issue,
   but for "protected" members. Should derived have "special" access
   to protected parts of base objects (other than their own base part).
   The ARM says no, because they are "unrelated" (11.2c, p.254),
   I was claiming that they are certainly NOT unrelated!
   Two different access rights on the SAME type of object...
   [access via "this" is different that via arguments or globals..]

   It was mislabeled because it was in followup to a message
   about private members..

For both the point was that type should be class wide,
not depending on which object was used.

I felt that this was especially important since many derived object may
interaact by talking to each other via base class pointer conversions.

Gregory Guthrie




Author: djones@megatest.com (Dave Jones)
Date: Thu, 12 May 1994 02:50:46 GMT
Raw View


Author: guthrie@miu.edu
Date: Mon, 09 May 94 21:24:00 CDT
Raw View
In article <CpKF1u.FL4@world.std.com>, <timk@world.std.com> writes:
> Newsgroups: comp.lang.c++
> From: timk@world.std.com (Tim King)
> Subject: Accessing private members in objects of a derived class
> Organization: The World Public Access UNIX, Brookline, MA
> Date: Tue, 10 May 1994 02:32:18 GMT
> Consider the following code:
> ---------------------------------------------------------------
>
> class A {
> public:
>     void F();
> private:
>     int X;            // I'm going to try to access X from A::F()...
> };
> class B : public A    // ... but I'm going to use an object of class B.
>   {};
> void A::F()
> {
>     B bVar;
>     bVar.X = 0;       // Here it goes!
> };
> ---------------------------------------------------------------
>> Is this behavior a MSVC bug?  If my code is bad, what's wrong with it?
> -TimK
> --
The bad news is that it is a "feature" not a bug.
(See ARM, p.254)
I have seen this surprise students (and myself) enough that I
have a proposal to change it;
any takers?!!

===------------------------------------------------------------===
** Proposal: change definition of protected access,
      allow any object of class to access protected portions...
                ------
 * Rationale:
      This is a known issue (ARM.254).
      The resolution given is not intuitive and limits common usage.
      It also goes against the general principle that access is a
      class property, not an object.
 * Background:
      The issue is if an object of Der should be able to access
      protected Base parts of any Der object, or only of itself.  The
      former would be a classwide permission, the later an object
      (instance based) approach. I see no advantage to breaking this
      general principle for this rule. It would allow one to have
      capabilities provided by a base class, which are available to
      all derived objects (on each-other), but not intended for
      outside users of the objects.  It is a natural part of the idea
      of collaboration of class objects. In fact, all access in class
      wide at any given level, and becomes only object based when base
      (inherited) capabilities are involved.  To me this is
      counter-intuitive; each object has the capabilities from the
      base, (Is-A), and this is a natural way to build the hierarchy.
      Yet, they cannot invoke these on each other.

      Example: a task class hierarchy.  One task decides to suspend,
      and to ask another to reschdule itself. Reschedule comes from
      the parent, is not for users (protected),  but for other cohort
      classes to use. Current rules prohibit this. The suspending
      object gets a pointer to the next task from a chain, and then
      wants to ask that task to reschedule, but it can't if reschedule
      came from the base class as a protected function.  This
      illustrates that the access to the reschedule function depends
      on the particular object, and Not only on the type of the object
      (can call on self, not on other).

      The ARM states in its commentary that the justifying example
      could have been solved through a different, (and more
      appropriate) design not requiring this rule. In general this is
      one example of a design capability, to provide a feature in a
      class, to be used only be members of that class (~private), and
      the ability to provide this capability through inheritance
      (protected).  The inherited feature should have the access
      features of a locally private feature at that level in the
      hierarchy, usable by all objects between themselves, but not
      outside the class.  The current rule doesn't allow this without
      re-implementation at each level (perhaps by a call-through..). I
      think this is a logical design limitation, and the rule is a
      mistake! The current rule makes inheritance (Is-A) work to the
      outside (public), but NOT inside the class; i.e. Der object d1
      cannot use d2 As-A Base object notably it cannot access
      protected capabilities.

      The rationale states that this is to prevent "access to the base
      class part of an unrelated class", but the class is NOT
      unrelated, it is a part of a common derivation hierarchy. Also,
      the commentary about protecting data in the base could probably
      be done by careful definition of the access functions provided
      to children classes.
 * Impact (Benefit):
      Greater range of expression.
 * Impact (Costs, compatibility):
      None.  The new rule is less restrictive, and thus upward
      compatible.
 * Other options:
 * Comments:
      This rule generally surprises C++ programmers, and although a
      rationale has been given, the fact that it is such a surprise
      is not a good sign!

===------------------------------------------------------------===





Author: timk@world.std.com (Tim King)
Date: Tue, 10 May 1994 22:37:46 GMT
Raw View
guthrie@miu.edu writes:

>> class A {
>> public:
>>     void F();
>> private:
>>     int X;            // I'm going to try to access X from A::F()...
>> };
>> class B : public A    // ... but I'm going to use an object of class B.
>>   {};
>> void A::F()
>> {
>>     B bVar;
>>     bVar.X = 0;       // Here it goes!
>> };

>The bad news is that it is a "feature" not a bug.
>(See ARM, p.254)
>I have seen this surprise students (and myself) enough that I
>have a proposal to change it;
>any takers?!!

Yes, I would think that this should be changed.  It is extremely
counter-intuitive.  bVar is an A, as well as it is a B.  Since it is an A,
it has a private member X, which should be accessible from within A::F().

A succinct illustration of the validity of the change is to rewrite A::F()
in the following, extremely clumsy manner, which is 100% compatible with
the spec:

  void A::F()
  {
      B bVar;
      ( (A*) &bVar) ->X = 0;
  }

&bVar is a pointer to an object of type B.  It can be cast to a pointer to
an object of type A, since an object of type B *is also* an object of type
A.  Using this pointer, we can validly access X from A::F().  Since this
all directly follows from the ARM, we can assume that it is indeed legal
to access bVar.X from A::F() without creating exceptions to the rules.  I
was just hoping that there was a more graceful syntax I could've used.

Oh well, I guess no one is perfect.
-TimK
--
         Tim King           I need a new sig!
    timk@world.std.com
      timk@ycrdi.com
                   All original material Copyright 1994 J. Timothy King




Author: jason@cygnus.com (Jason Merrill)
Date: Wed, 11 May 1994 02:53:54 GMT
Raw View
>>>>> Tim King <timk@world.std.com> writes:

> bVar is an A, as well as it is a B.  Since it is an A, it has a private
> member X, which should be accessible from within A::F().

Indeed it should.  From the latest WP:

           A  friend or a member
  function of a derived class can access a protected nonstatic member of
  one  of  its  base classes only through a pointer to, reference to, or
  object of the derived class itself (or any  class  derived  from  that
  class).

I would assume that this would apply to accessing a member of the derived
class itself, as well.

Jason




Author: fenster@age.cs.columbia.edu (Sam Fenster)
Date: 11 May 1994 19:55:38 GMT
Raw View
> >>>>> Tim King <timk@world.std.com> writes:
> > bVar is an A, as well as it is a B.  Since it is an A, it has a private
> > member X, which should be accessible from within A::F().

If derived classes could access private base class members, encapsulation
would be lost.  B "is an" A to the outside world, but this does not mean that
its private implementation has access to A's private implementation.

> Indeed it should.  From the latest WP:
>            A friend or a member
>   function of a derived class can access a protected nonstatic member of one
>   of its base classes only through a pointer to, reference to, or object of
>   the derived class itself (or any class derived from that class).

Indeed, "protected" base class members do what you want.  "Protected" was
added to C++ for exactly this reason.  "Private" need not change.




Author: hartman@ulogic.UUCP (Richard M. Hartman)
Date: 11 May 94 16:56:52 GMT
Raw View
Hey, we're both instances of the class "Human", but I don't want
YOU fiddleing with MY private parts! <g>

In other words -- I think that "private" should be private to the
instance, not the class and especially not it's descendants.

... on the other hand, with the SCO development system, the example
you provided works just fine <g>

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
But now I'm grasping   |
that understanding   | -Richard Hartman
is only part of love.   | hartman@uLogic.COM