Why is this allowed? Inheritance variable shadowing

Mike Parker aldacron at gmail.com
Tue Aug 13 05:57:23 UTC 2019


On Tuesday, 13 August 2019 at 04:40:53 UTC, Chris Katko wrote:
> You can drop this straight into run.dlang.io:
>
> import std.stdio;
>
> class base{ float x=1;}
> class child : base {float x=2;} //shadows base variable!
>
> void main()
> {
>
>     base []array;
>     child c = new child;
>     array ~= c;
>
>     writeln(c.x); //=2
>     writeln(array[0].x); //=1  //uses BASE's interface, yes,
>     //but why does the CHILD instance one exist at all?
> }
>
> It appears to be legal C++ as well but I can't imagine a 
> situation where you'd want to allow the HUGE risk of 
> shadowing/aliasing variables in an child class. Why is 
> inheritance shadowing allowed? Especially when in D you have to 
> explicitly "override" existing _methods_ but not 
> fields/variables?
>
> To quote a Stack Overflow comment on C++ having this "It's not 
> a compile error, but it's certainly a design one." Is this 
> allowed just because "C++ does it" or because it has some sort 
> of real world use that justifies the risk?
>
> Personally, I'd love a compile-time warning that I could turn 
> on that flags this situation.
>
> Thanks for your help,
> --Chris

I don't know if I'd call that shadowing. This is how it works in 
Java, too. There's no such thing as a vtable for member variables 
-- each class gets its own set and they don't conflict. The only 
time it could be really be called shadowing is when the base 
class member is protected, as then it's accessible in the 
subclass scope.

Also, it's not the same thing as overriding. Overriding means 
that when you call base.foo(), you get sub.foo()'s 
implementation. But when you access base.var, you get base.var 
and not sub.var.

I would find it extremely annoying if it worked the way you're 
expecting it to.


More information about the Digitalmars-d-learn mailing list