Does type casting work
BlitzMax Forums/BlitzMax Beginners Area/Does type casting work
| ||
Here is an arbitary exampleType TBase Field FOne:Int '--------------------------------------------- Function Create:TBase () Local Temp:TBase = New TBase Temp.FOne = 1 Return Temp End Function EndType '---------------------------------------------- Type TExtend Extends TBase Field FTwo:Int '--------------------------------------------- Function Create:TExtend () Local Temp:TExtend = New TExtend Temp.FTwo = 2 Return Temp End Function End Type Global mine:TBase = TBase.Create() Print mine.FOne Print TExtend(mine:TBase).FOne When run it prints the value of Mine:Tbase.Fone then it casts TBASE to TExtend. BUT it dosent even do a field copy? Because when I then ask for FOne, its a different number |
| ||
Tell me, when you're using C++ and you do this:BaseClass* c = new BaseClass(); DerivedClass* d = (DerivedClass*)c; Do you expect d to be a valid DerivedClass? |
| ||
Dont know I cannot program in c++ but in bmax, if at the end of above you Global newmine:TExtend= TExtend(mine:TBase) then yes I expect newmine to be an extend type, and it is. The problem isnt that it doesnt create a valid object, the problem is that it doesnt copy any of the fields |
| ||
Type TBase Field FOne:Int '--------------------------------------------- Function Create:TBase () Local Temp:TBase = New TBase Temp.FOne= 1 Return Temp End Function EndType '---------------------------------------------- Type TExtend Extends TBase Field FTwo:Int '--------------------------------------------- Function Create:TExtend () Local Temp:TExtend= New TExtend Temp.FTwo= 2 Return Temp End Function End Type Local mine:TBase = TBase.Create() Print mine.FOne Local mine2:TExtend = TExtend( mine ) Print mine2.FOne Input Does this work? It shouldn't. |
| ||
Thats the same as my code. It works in so far as local mine2:Textend = Textend (mine) creates a valid extend object. But it doent work in that mine2 contains NON of the values of mine. But all you are doing is saying look it doesnt work, which is what I said. What I would like to know, is exactly what has the textend(mine) done, other than create a textends type. Surly it should have field copied the base fields into the extend type TAnyType(ABaseObject) Basicaly you are saying TAnyType(ABaseObject) is the same as New TAnyType In that they both create a TAnyType. Surly the cast method should copy somthing from ABaseObject? |
| ||
TExtend(mine) doesn't create a TExtend object. What version of BlitzMax are you using? Think of it this way, or even draw up a venn diagram if you have to, it's very simple though: A pie is a dessert, but a dessert is not a pie. Casting works only when you create an object of the correct type and either upcast or downcast to its appropriate base or derivation. When you create a TBase and cast it to a TExtend, it should not ever work and it definitely should not be creating a new object. Your program should, in fact, throw a runtime error if you attempt to cast a new instance of TBase (note: NOT a new instance of TExtend) to a TExtend and then use said TExtend. It's like saying that dessert is the same thing as pie and vice versa when in fact pie is a derivative of dessert and dessert is not a derivative of pie. Casting is not copying. |
| ||
What can I sayGlobal mine:TBase = TBase.Create() Print mine.FOne Global newmine:TExtend = TExtend(mine) Print mine.FOne Print newmine.FOne+","+newmine.FTwo mine.FOne:+999 newmine.FOne:+ 1 Print mine.FOne Print newmine.FOne+","+newmine.FTwo Put this at the end of the first example. I am using todays version of Bmax, and if you run the above it dosent crash. TExtend(Mine) does seem to create a Textend Object, yet this object Dosent have any of the values of Mine. Can you please post a copy of cast that works? (Objects not Types) I am willing to admit that I have totaly missunderstood the meaning of casting, (But NOT soon;-) |
| ||
1 1 ~>Unhandled Exception:Attempt to access field or method of Null object ~> t ~>StackTrace{ ~>@C:/Documents and Settings/Owner/Desktop/tf.bmx<25,1> ~>Function tf ~>Global mine:TBase=$00ea1d30 ~>Global newmine:TExtend=Null ~>} ~> It does crash. |
| ||
Compiling:uu.bmx flat assembler version 1.64 3 passes, 0.1 seconds, 4050 bytes. Linking:uu.exe 1 1 0,0 1000 1,0 Not on mine Full code |
| ||
Are you compiling in debug or release mode? |
| ||
Release |
| ||
Compile in debug. |
| ||
Doesnt work in debug. (But Maybe thats a promblem in Debug ;) |
| ||
Why? If it works in relese it works. (ie when the product is released it works) If it dosent work in debug, its a problem with debug. (But I already did) And got your result. BUT (Thats a big but) I think this shows that a new object IS created, and there is a problem with debug Wrong. If it doesn't work in debug, then your code is bad. It could be bad in any number of ways, but currently it's bad in that you're accessing memory that is not allocated for the type in question. A new object is not created. I don't know where you get this idea, honestly. What you're doing is accessing memory that you just shouldn't be accessing. Release mode removes checks for these things, and the problem is your code isn't checking for these faults because it's being compiled in release. So, in fact, your code is bad and you're wrong. (Editing your post cannot save you from the browser cache) |
| ||
After you click OK on the Unhandled Exception in debug mode, look over to the Debug tab of the IDE. There you will see Function untitled... or whatever your test code is named. If you expand that you will see newmine is infact null which is what you get if you try and cast something in the wrong direction. BlitzMax allows you to downcast but upcasting results in a null object, not some copy of the orginal type with extra fields as seems to be your expectation. |
| ||
@My old post. I Know I realized how stupid that was as soon as I posted it. It was edited straight away. Sorry So does Type casting work? @Casting works only when you create an object of the correct type and either upcast or downcast to its appropriate base or derivation Type TExtend extends TBase Surly the base of Textend is TBase. And surly a derivation of TBase if TExtend etc. Oh come on Post me some code where it works, cos Ive spent all day on this (and the overridding thing) and Im stuck. I admit it. I CANNOT figure it out by myself. Please sombody tell how to use the cast stuff. |
| ||
SuperStrict Type Base Field BField% End Type Type Derived Extends Base Field DField% End Type ' This is a legitimate use of casting Local d:Derived = New Derived ' A Derived is a Base but a Base is not a Derived, REMEMBER. Local b:Base = Base(d) ' Same as b = d, but explicitly downcasted for the sake of example d = Derived(b) ' Pretty much the same as d=d ' This is not b = New Base d = Derived(b) ' A Derived is a Base but a Base is not a Derived b = Base(d) |
| ||
I'd recommend this excellent OOP tutorial http://www.blitzmax.com/Community/posts.php?topic=59233 |
| ||
Tar. |
| ||
Can the Local b:base by created/invoked/named any other way than the one you have used? @Assari Already got it |
| ||
No. |
| ||
Ahhhh. Then yes I have TOTALY missed the point of casting :( I thought casting was "Ive got a base, and I want to make a derived, so I cast the base, and Yippy I have a Derived" I would like to appologise If Ive been ratty on this or the Override Create thread. |
| ||
Casting base to derived only works if the stuff saved within the base was already a derived casted to base. (ie you can only downcast the inheritance tree if the element was first upcasted the inheritance tree) |