Why do private member variables behaved like protected in the same module when creating deriving class?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri Oct 26 22:54:51 UTC 2018


On Friday, October 26, 2018 3:25:05 PM MDT 12345swordy via Digitalmars-d 
wrote:
> On Friday, 26 October 2018 at 20:55:00 UTC, Jonathan M Davis
>
> wrote:
> > On Friday, October 26, 2018 1:55:08 PM MDT 12345swordy via
> >
> > Digitalmars-d wrote:
> >> On Friday, 26 October 2018 at 19:45:48 UTC, David Gileadi
> >>
> >> wrote:
> >> > [...]
> >>
> >> If it deliberate, then it needs to be documented.
> >
> > What are you asking for exactly? The documentation documents
> > exactly what the behavior is:
> >
> > https://dlang.org/spec/attribute.html#visibility_attributes
> >
> > "2. Symbols with private visibility can only be accessed from
> > within the same module. Private member functions are implicitly
> > final and cannot be overridden."
> >
> > Are you looking for the documentation to explain why there is a
> > "loophole" to private that allows other symbols within a module
> > to access private members of a class of struct?
>
> No I am asking why class B inherent the private variables of
> class A that is marked private, when we have the protected
> keyword.
>
> I don't know how else I can I make this any clearer.

If class B is in the same module as class A, it has access to all private
members of class A. It comes from the fact that private is private to the
module, not private to the class. private has _nothing_ to do with
inheritance. As the documentation clearly states, "symbols with private
visibility can be accessed from within the same module." The idea that any
derived classes in the same module would then somehow not have access comes
from assumptions based on how other languages work, not from how D works or
how it's documented to work.

protected makes it so that derived classes - whether they be in the same
module or elsewhere - can access that member. It also makes functions
virtual. So, it _does_ have something to with inheritance. private, however,
only has to do with modules. It has no affect on inheritance and does not
make functions virtual.

Similarly, package makes it so that other symbols within the same package
can access that symbol. It has no effect on inheritance and does not make
functions virtual.

public is the only other attribute that affects inheritance or makes
functions virtual, and it gives full access.

Don't assume that the various access levels work the way that they do in
other languages that you've used, because odds are that they don't. Aside
from the fact that export needs to be better explained, they work the way
that the spec describes them:

https://dlang.org/spec/attribute.html#visibility_attributes

Your confusion stems from the fact that you're fixating on trying to
restrict access at the class level, and that is _not_ how D is designed to
work. The _module_ is the base level of encapsulation that D uses. package,
protected, and public all provide ways to expand access - to the package,
derived classes, and everything else respectively. But the idea that you're
ever restricting access to the class or struct specifically is just plain
false. If you want to do that, you need to put that class or struct in a
module by itself. As soon as you put it in a module with _anything_ else -
including derived classes - those other symbols are going to have access to
the private members of that class or struct.

If you don't like that design decision, that's fine. As with almost all
design decisions, there are pros and cons to it, but that doesn't mean that
it has "holes" in it. It means that it defines private to mean something
different from what C++, Java, C#, etc. define it to mean, and you're going
to have an easier time here if you stop assuming that private means the same
thing in D that it means in other languages or that it's even intended to
mean the same thing.

You seem to keep making the mistake that visibility attributes have anything
to do with restricting access at the class level in D, and they _never_ do.
If you put other stuff in a module with a class, then that other stuff is
going to have access to that class' members no matter what access level
those members have. The visibility attributes affect which symbol outside of
the module can then access those members, and in the case of member
functions, it affects whether they're virtual, but it never affects whether
anything else inside the module can access them.

- Jonathan M Davis





More information about the Digitalmars-d mailing list