Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
January 21, 2008 Casting from interface to real class? | ||||
---|---|---|---|---|
| ||||
Is it possible to do a dynamic cast from an interface to a real class? SomeClass k = cast(SomeClass)anInterface; will that succeed if anInterface started life as a SomeClass? --bb |
January 21, 2008 Re: Casting from interface to real class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote: > Is it possible to do a dynamic cast from an interface to a real class? > > SomeClass k = cast(SomeClass)anInterface; > > will that succeed if anInterface started life as a SomeClass? I think I found the answer: Yes. http://spottedtiger.tripod.com/D_Language/D_FAQ_XP.html """ Casting from an interface back to the class means subtracting that offset. The subtract is a little tricky since the pointer doesn't know where it came from, so the first entry in the interface's vtbl[] is an instance of the class Interface with the necessary offset. The cast is handled by the library function _d_interface_cast(). """ --bb |
January 21, 2008 Re: Casting from interface to real class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Hi Bill, Bill Baxter Wrote: > Bill Baxter wrote: > > Is it possible to do a dynamic cast from an interface to a real class? > > > > SomeClass k = cast(SomeClass)anInterface; > > > > will that succeed if anInterface started life as a SomeClass? > I hope I understood your question correctly, here is an example. -------------------- import std.stdio; interface Expr { Expr type(); void print(); } Expr steSymbol; class Symbol : Expr { public: this(char [] name) { this.itsName = name; } char [] getName() { return this.itsName; } Expr type() {return steSymbol;} void print() {writefln(this.itsName);} private: char [] itsName; int itsInt; } int main ( char [][] arg ) { Expr e; steSymbol = new Symbol("Symbol"); e = new Symbol("x"); steSymbol.print(); e.print(); e.type().print(); Symbol s = cast(Symbol)e; s.print(); writefln((cast(Symbol)e).getName()); return 0; } |
January 21, 2008 Re: Casting from interface to real class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oliver | Oliver wrote:
> Hi Bill,
>
> Bill Baxter Wrote:
>
>> Bill Baxter wrote:
>>> Is it possible to do a dynamic cast from an interface to a real class?
>>>
>>> SomeClass k = cast(SomeClass)anInterface;
>>>
>>> will that succeed if anInterface started life as a SomeClass?
>
>
> I hope I understood your question correctly, here is an example.
>
> --------------------
> import std.stdio;
>
> interface Expr {
> Expr type();
> void print();
> }
>
> Expr steSymbol;
>
> class Symbol : Expr { public:
> this(char [] name) { this.itsName = name; }
> char [] getName() { return this.itsName; }
> Expr type() {return steSymbol;}
> void print() {writefln(this.itsName);}
> private:
> char [] itsName; int itsInt;
> }
>
> int main ( char [][] arg ) { Expr e;
> steSymbol = new Symbol("Symbol");
> e = new Symbol("x");
> steSymbol.print();
> e.print();
> e.type().print();
> Symbol s = cast(Symbol)e;
> s.print();
> writefln((cast(Symbol)e).getName());
> return 0;
> }
>
>
Yep, that's exactly what I was hoping I could do but thinking I couldn't. But it does work. Happy day.
--bb
|
January 21, 2008 Re: Casting from interface to real class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter Wrote: > Oliver wrote: > > Hi Bill, > > > > Bill Baxter Wrote: > > > >> Bill Baxter wrote: > >>> Is it possible to do a dynamic cast from an interface to a real class? > >>> > >>> SomeClass k = cast(SomeClass)anInterface; > >>> > >>> will that succeed if anInterface started life as a SomeClass? > > > > > > I hope I understood your question correctly, here is an example. > > > > -------------------- > > import std.stdio; > > > > interface Expr { > > Expr type(); > > void print(); > > } > > > > Expr steSymbol; > > > > class Symbol : Expr { > > public: > > this(char [] name) { this.itsName = name; } > > char [] getName() { return this.itsName; } > > Expr type() {return steSymbol;} > > void print() {writefln(this.itsName);} > > private: > > char [] itsName; > > int itsInt; > > } > > > > int main ( char [][] arg ) { > > Expr e; > > steSymbol = new Symbol("Symbol"); > > e = new Symbol("x"); > > steSymbol.print(); > > e.print(); > > e.type().print(); > > Symbol s = cast(Symbol)e; > > s.print(); > > writefln((cast(Symbol)e).getName()); > > return 0; > > } > > > > > > Yep, that's exactly what I was hoping I could do but thinking I couldn't. But it does work. Happy day. > > --bb there is one, caveat though. If you overload opEquals you need to cast to object to make that work, which is very ugly in the code. int opEquals( Object o ) { Symbol s = cast(Symbol)o; return s && this.itsName == s.itsName; } and calling looks ugly, something like: assert( cast(Object)e1 == cast(Object)e2 ); I think the problem comes from the fact that interface can also be a COM interface. http://www.digitalmars.com/d/archives/digitalmars/D/Object_and_interface_compatibility_48235.html should you find a way to avoid the cast, i'd be very interested to see that, otherwise happy coding ;-) |
Copyright © 1999-2021 by the D Language Foundation