Is there a keyword to access the base class
Steven Schveighoffer
schveiguy at yahoo.com
Thu Jun 20 05:32:23 PDT 2013
On Wed, 19 Jun 2013 19:10:39 -0400, Stephen Jones <siwenjo at gmail.com>
wrote:
>> Hm... would be a nice idiom to implement generically in D. Like a type
>> switch.
>>
>> -Steve
>
> That is what I would prefer, but I tried:
>
> writeln(to!(typeof(bars[1]))(bars[1]).val);
>
> to see if I could access the "DERIVED" (thanks) class type but even
> though bars[1] is initialized as a new Foos its type is still marked as
> Bar. So the question is, how do you find the derived class type when
> presented with only the super class?
You have to understand, D is statically typed. There are two types
involved here, the dynamic, object-oriented type, which is only known at
runtime, and the static type which is known by the compiler.
typeof(bars[1]) gets the *static* type, or the type that the compiler
knows. bars is a Bar[], so the compiler only knows that bars[1] is a Bar.
The dynamic type of bars[1], as we know, is Foos. And bars[1] knows it
too, but in order to call a function on a derived type, the *compiler* has
to know it. So when you say something like:
if(auto der = cast(Foos)bars[1])
You are telling the compiler:
"OK, I know this is a Bar right now, but check during runtime to see if
this is actually a Foos. If it is, branch in here with 'der' as a
variable which is statically typed as Foos."
Then the compiler can know inside that branch, that it can access bars[1]
via the static type Foos, and you have access to all Foos' members. Note
that if the instance is actually a derivative of Foos, the compiler STILL
will go into that branch!
The "correct" way to do this is to define what you are looking for as a
virtual or abstract method on the base class/interface, and then the
compiler does all this work for you (but it's only a vtable lookup, so
it's much faster).
But if you DON'T know that all derivatives will support 'val' (and you
have to know this when the base class is written), then you have to do
this casting dance.
Dynamically typed languages make this easier, but it comes at a price.
Statically typed languages have the compiler check so much more at compile
time, so it's much more difficult to make a mistake. I deal with this all
the time on PHP, where you can simply type a variable name wrong, and the
compiler (and sometimes during runtime) won't complain, it just thinks you
are declaring a new variable on an object instance.
Note that Ali's suggestion of typeid does NOT give you a static type of
the most derived type, it's a runtime type information object that has
limited capability. It's like reflection in Java or .Net. But much less
powerful, since D's TypeInfo does not provide a full mapping of members
that is able to call methods and whatnot.
So while typeid can tell you what the type is (good for comparing, etc),
you can't call methods on it (well, there are a couple, like comparing two
objects, but not arbitrary ones).
-Steve
More information about the Digitalmars-d-learn
mailing list