Is it a bug that a parent class that access its own private members from derived classes gets deprecation warning?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Wed Apr 11 17:58:25 UTC 2018


On Sunday, April 08, 2018 13:00:02 bauss via Digitalmars-d wrote:
> On Sunday, 8 April 2018 at 10:48:19 UTC, user1234 wrote:
> > On Saturday, 7 April 2018 at 20:46:39 UTC, bauss wrote:
> >> On Saturday, 7 April 2018 at 20:34:57 UTC, user1234 wrote:
> >>> On Saturday, 7 April 2018 at 20:14:49 UTC, bauss wrote:
> >>>> jesus that became a long title.
> >>>>
> >>>> Anyway as the title says, is it a bug that a parent class
> >>>> that access its own private members from derived classes
> >>>> gets deprecation warning?
> >>>
> >>> If the import is selective no. (`import foo : Foo;`)
> >>> If the import is for the whole module i'd say yes. (`import
> >>> foo;`)
> >>
> >> What do you mean?
> >>
> >> The problem is that "Foo" cannot access "_baz" without
> >> deperecation warning, but "_baz" is a part of "Foo".
> >
> > _baz is private and not protected. The deprecation was
> > introduced because bug 314 broke the private protection.
>
> I think it's better demonstrated like this, because to me the
> behavior makes no sense.
>
> Especially since you can just cast "Bar" to "Foo" and then you're
> allowed to do it.
>
> Since we're inside Foo then it shouldn't care whether "_baz" is
> private or not.
>
> I could understand if the function was located within Bar, but
> it's not.
>
> It's perfectly normal in other languages that supports classes to
> access private members of parent's as long as you're within the
> parent's encapsulation.
>
> // a.d
> module a;
>
> class Foo
> {
>   private:
>   bool _baz;
>
>   public:
>   void handleBar(T : Foo)(T[] foos)
>   {
>       foreach (child; foos)
>       {
>           child._baz = true; // Not ok.
>           (cast(Foo)child)._baz = true; // Ok.
>       }
>   }
> }
>
> // b.d
> module b;
>
> import a;
>
> class Bar : Foo
> {
>
> }
>
> // main.d
>
> module main;
>
> import b;
>
> void main()
> {
>   auto bars = [new Bar, new Bar];
>   auto bar = new Bar;
>   bar.handleBar(bars);
> }

I don't know. It could be argued either way. I think that the logic as to
why

child._baz = true;

is not legal is because you're accessing it through a class reference that
does not have access to _baz, since it's private to the base class. Allowing
access to the base class member via a derived class reference arguably
violates private.

On the other hand, this is inside a member function of the base class, and
the base class has access to the private members - even if they're in an
object other than the current one. And by that logic, it should be legal to
access the base class member even though it's through a derived class
reference.

Usually, base classes don't handle any references for derived classes (they
may handle derived classes through base class references but not usually
through actual derived class references), and this sort of thing doesn't
come up. As such, I think that the obvious result would be the current
behavior regardless of whether that is actually the best behavior.

I suspect that this particular situation was never really thought through in
the implementation, but I don't know. And since I think that there are good
arguments in both directions, I really don't know whether the current
implementation is better or whether what you're trying to do should be
legal. Certainly, it seems like a valid enhancement request, though I have
no idea whether Walter would think that what you're trying to do should work
or not. I wouldn't be surprised either way.

- Jonathan M Davis



More information about the Digitalmars-d mailing list