Casting a pointer in Turing
Author |
Message |
DemonWasp
|
Posted: Tue Feb 17, 2009 4:33 pm Post subject: Casting a pointer in Turing |
|
|
I searched this forum, but couldn't find anything that makes mention of this. If I'm duplicating something somewhere else, it's by accident.
You may have noticed that Turing doesn't have a way of casting a base-class-pointer to a derived-class-pointer like most other languages. In Java you would just do
code: |
DerivedClassName derived = (DerivedClassName)base;
|
No such luck in Turing. But, there IS a way. It's grisly though, so those with an aversion to horrific implementations may want to avert their eyes.
Turing: |
% Pointer-casting Example
class Base
export baseMember
var baseMember : int := Rand.Int(1, 10)
end Base
class Derived
inherit Base
export derivedMember
var derivedMember : string := "abcdefg"
end Derived
var myDerivedObject : ^Base
new Derived, myDerivedObject
put myDerivedObject->baseMember
% This line gives the warning: "'derivedMember' is not in the export list of base"
% Which is of course correct, but unhelpful. It CAN'T be there, as it's only in the derived class.
%put myDerivedObject->derivedMember
type DerivedPtr : ^Derived
var myDerivedPtr : DerivedPtr := cheat ( DerivedPtr, myDerivedObject )
% Now we've successfully cast a base ptr to a derived ptr. Be warned, cheat is DANGEROUS. Only cast if you're SURE.
put myDerivedPtr -> baseMember
put myDerivedPtr -> derivedMember
|
Weirdly enough, you can't just use ^Derived in place of DerivedPtr there. Turing expects an identifier, which apparently doesn't include pointers. By making an object-ptr type, however, you can easily cast to that type with just one line.
edit: Quotefail |
|
|
|
|
|
Sponsor Sponsor
|
|
|
saltpro15
|
Posted: Tue Feb 17, 2009 4:44 pm Post subject: RE:Casting a pointer in Turing |
|
|
I did not understand more than 3 words of that program, what the heck does a "cheat" do? better yet, what does any of it do ? |
|
|
|
|
|
DemonWasp
|
Posted: Tue Feb 17, 2009 5:03 pm Post subject: RE:Casting a pointer in Turing |
|
|
If you haven't read Cervantes' tutorial on Turing Classes, start there. Otherwise...
Basically:
You have two classes, call them "Base" and "Derived". Derived inherits from Base, so we can say "Derived is a Base" but we CANNOT say "Base is a Derived" because that's not always true.
Turing understands that, so any variable you have that is defined as a pointer-to-Derived can access all the methods exported by Base, because it IS a Base.
However, there are numerous circumstances where you have to be more specific. What if you need one of the methods that's only implemented by Derived, but for some reason you have to access it within a variable declared as ^Base (pointer-to-Base)?
Well, then you have to do what's called "casting". This just means "assume that this variable is a pointer-to-Derived, even though we don't know that for sure". Once we've done that (assuming it worked out...), we can access all the more specific fields and elements.
Update: I took a look at what it does if you use cheat() to cast to something that it isn't. It looks like Turing will let you do it, no matter how dangerous it is; the result is something like unions in C. Try the following:
Turing: |
% Pointer-casting Example
class Base
export baseMember
var baseMember : int := Rand.Int(1, 10)
end Base
class Derived
inherit Base
export derivedMember
var derivedMember : string := "abcdefg"
end Derived
class Derived2
inherit Base
export derivedMember
var derivedMember : array 1..256 of nat1
end Derived2
var myDerivedObject : ^Base
new Derived, myDerivedObject
put myDerivedObject->baseMember
% This line gives the warning: "'derivedMember' is not in the export list of base"
% Which is of course correct, but unhelpful. It CAN'T be there, as it's only in the derived class.
%put myDerivedObject->derivedMember
type DerivedPtr : ^Derived
var myDerivedPtr : DerivedPtr := cheat ( DerivedPtr, myDerivedObject )
% Now we've successfully cast a base ptr to a derived ptr. Be warned, cheat is DANGEROUS. Only cast if you're SURE.
put myDerivedPtr -> baseMember
put myDerivedPtr -> derivedMember
% Now let's do a (supposedly) illegal cast...
type DerivedPtr2 : ^Derived2
var myDerivedPtr2 : DerivedPtr2 := cheat ( DerivedPtr2, myDerivedObject )
% Whoops, looks like we can output the derivedMember string as if it were a byte array!
put myDerivedPtr2->derivedMember(1)
put myDerivedPtr2->derivedMember(2)
put myDerivedPtr2->derivedMember(3)
put myDerivedPtr2->derivedMember(4)
put myDerivedPtr2->derivedMember(5)
put myDerivedPtr2->derivedMember(6)
put myDerivedPtr2->derivedMember(7)
|
|
|
|
|
|
|
saltpro15
|
Posted: Tue Feb 17, 2009 6:27 pm Post subject: RE:Casting a pointer in Turing |
|
|
ah, thanks |
|
|
|
|
|
DemonWasp
|
Posted: Mon Apr 20, 2009 4:49 pm Post subject: RE:Casting a pointer in Turing |
|
|
Resurrects to point something out:
Turing's documentation is full of fail. Turns out there's an anyclass root class (like Java's Object class). In the documentation for that class, it notes the following:
You can make a cast (with type-checking) from base-ptr to derived-ptr as follows:
Turing: |
var p : ^ anyclass
new stack, p
stack ( p ) . push ( 14 )
|
It's a little cleaner. |
|
|
|
|
|
kalev
|
Posted: Thu Apr 23, 2009 9:00 am Post subject: Re: Casting a pointer in Turing |
|
|
theres an easier way to cheat:
Turing: |
var variable1:char
var variable2:int
variable2:= 50
#variable1 := variable2
|
opposed to:
Turing: |
var variable1:char
var variable2:int
variable2:= 2
variable1 := cheat (char, variable2)
|
note: the first way is shorter, and doesn't need to know the type of variable1 or variable2 |
|
|
|
|
|
|
|