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