|
![](/i/fill.gif) |
Warp wrote:
>> Like, in unsafe languages, where a stray pointer can change private
>> variables without going thru the class methods? :-)
>
> No. The reasoning behind data hiding in modular thinking is completely
> independent of the language used. It has to do with program design.
OK. I guess you look it as "if you bypass the documentation and access
members not documented, I have to support your brokenness forever." I look
at it as "if you're coding from the implementation instead of the
documentation, you get what you deserve" combined with "don't make me debug
my code when the bug is in your code."
> If you expose the internal structure of a module to the outside, then
> there's a big chance that outside will start making *assumptions* about
> this internal structure.
Sure. Most of these languages (a) document what's public and what isn't, and
(b) have a language-wide naming convention for it. That is, after all, what
C++'s 'private' tag is - a naming convention.
> If this happens, then you can't change the internal implementation of
> this module without breaking existing code. For example, if you wanted
> to change the color components to floats, or you would want to pack the
> color components into one single integral value, you will most probably
> break existing code (especially probable in the latter case, as the
> amount and names of the member variables will change drastically).
>
> If you can design the absolutely perfect module which will never change
> its contents and will suffice for years to come, then by all means make
> all members public. Us mortals will try smarter techniques.
>
>> C# and Java both have reflection that let you get to private members from
>> outside.
>
> Thus it's one reason why the design of these languages is badly broken.
I think it's more a trade-off than you make it out to be.
>> C++ not only lets you return pointers to private members
>
> Only if the class itself explicitly does so. You can't get to the private
> members *from the outside*.
That's why I said it wasn't much of a breakage in my view.
> (Well, at least not without some serious hacking.)
Running off the end of an array is "serious hacking"? I wouldn't think so.
> I don't understand what you are saying. If a class in C++ does not expose
> a member array, then you can't get to that member array from the outside,
int * p = (int *) 0x123456;
*p = 27;
Find the bug in your code that's setting that member variable to 27.
How about
// Your code...
class xyz {
public: int[10] x;
private int y = 0;
}
// My code
xyz pdq;
pdq.x[10] = 27;
> You might be able to control your *own* code from not misusing public
> variables (and you might never make mistakes), but it's more difficult to
> control someone else.
Sure. See above examples.
> If you need to tell someone else "don't access member variables whose
> name start with an underscore", that's just plain stupid. You should be
> able to tell that by making the *compiler* enforce it.
I agree, except for the fact that you're using C++ as an example. :) C++ has
it's own different lack-of-modularity problems. If the compiler actually
*enforces* that the member variables you declare private can only be changed
by your own methods, that's great.
"don't access member variables whose name starts with an underscore" is the
kind of rule that's enforced all through a codebase or a programming
language. The little extra warning the compiler is going to give you is
generally not of much benefit if someone's going to violate that rule
anyway, IME. In other words, if they really need to violate the privacy of
your class, they're going to do it in C++ almost as easily as they do it in
something like Python or LISP. The compiler doesn't enforce the
encapsulation in C++ - it just gives warnings when you use a variable name
that's private. There's no enforcement at runtime, and plenty of back doors
at compile time. Contrast with, say, C#, where you don't even know what the
private variables are named, and you couldn't access them if you did,
because the runtime enforces that - there, the only backdoor is the
reflection libraries that specifically are bypassing the privacy checking
system. Using reflection (or explicitly assigning to _private members) isn't
any more common or more prone to abuse than ((int*)0x12345)=27; is,
particularly because the user has to explicitly know they're violating
encapsulation when they write the code.
Granted, if you don't *document* in a universal kind of way what's public
and what isn't, you're leaving yourself open to abuse.
But there are a lot of people who don't want to write a ton of boilerplate
code for a function that could be automated, so they're willing to say "if
you use introspection to read and write my structure over the wire, be
aware it may change in other versions." It's better to say "this will break
with future versions" than to say "I'm going to write 5000 lines of
boilerplate code to allow clients to send my values over the internet or
into databases."
There are also a whole bunch of assumptions in your classes that someone is
going to rely on that you're not going to be able to prevent. SimCity
assumed memory you called free() on would still be valid until the next
malloc(), which is obviously a bad assumption yet still has to be supported
by the infrastructure if you expect to run simcity on later versions of the
OS. If you store your object outside of memory or interact with any other
objects, you're also going to have random dependencies created - someone is
going to have to change database schemas to store your objects in a
database, or change buffer sizes if you switch from JSON serializiation to
XML serialization without otherwise changing your interface. There will be
people who assume your class only invokes their getter method once, if
that's how you first code it, and if you change to invoking it twice, they
may very well fail out (because they're pulling the next row from a database
for each invocation, say). Or, in short, you can't protect against bad
programmers, and anyone half-decent isn't going to be frobbing private
variables to start with, IME.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
![](/i/fill.gif) |