Operator To : Cast Self to Derived Class

About Monkey 2 Forums Monkey 2 Programming Help Operator To : Cast Self to Derived Class

This topic contains 7 replies, has 3 voices, and was last updated by  arpie 1 year, 5 months ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #11663

    arpie
    Participant

    This results in a memory access violation at runtime :

    But this is fine :

    And this also appears to work :

    Is the failing of cast<DerivThing>(Self) a bug?

    Is my convoluted casting via a VarPtr actually hiding a subtle gotcha that I haven’t noticed that will bite me later if I use this code (assuming, of course, I implement checks that the object is definitely of the right subclass before I cast it)?

    TIA

    #11664

    Mark Sibly
    Keymaster

    Sort of a bug, it’s actually recursing to death as To:Derived is calling Cast<Derived> which is calling To:Derived etc etc.

    Not sure of allowing operator To to downcast is such a great idea, could live without it myself but will think about it.

    (VarPtr slf)[0])

    Please don’t use this anymore, it’ll probably be going soon, along with any sort of ‘Object Ptr’ types.

    If you really, really need the adress of an object, you can now use Cast<Void Ptr>( obj ) but of course be careful as the returned pointer will become invalid if the object is GCed, ie: it’s up to you to keep the object alive while you are using the pointer.

    #11665

    arpie
    Participant

    Getting a memory access violation was a surprise – you usually do a very thorough job, Mark, of catching this sort of thing at compile time and giving us useful, to-the-point error messages!

    I agree, I could live without downcasting in Operator To, but I don’t see that as a reason not to ‘fix’ this ‘sort-of-bug’ if it is not too complicated (when you have 5 minutes to spare :).  I could also live without ever doing any type casting at all… but one day I might wish it was availaible!

    So for now, to make this work, I can do it like this :

    ?

    Actually, this also seems to work :

    Is there any reason I shouldn’t use this?

    #11666

    ImmutableOctet
    Participant

    Why wouldn’t you just make the dynamic cast outside of the class to begin with? Even then, if you need to dynamically cast to a derived class from the base class, why not put the functionality you need in the base class to begin with… At the very least, why aren’t you using ‘Virtual’ methods instead of casting? Dynamic casting is slower, so you don’t have that excuse.

     

    This looks like a design smell.

    #11667

    arpie
    Participant

    Having just praised your error messages, I just typed :

    Local a = 15

    And got the error ‘Expecting end of line’, which seems a bit cryptic.

    I’m sure it used to tell me I had missed out the variable type specifier (or := operator).  Have I imagined that?

    Sorry, I’ve gone off topic!

    #11668

    arpie
    Participant

    @immutableoctet I agree it smells bad on the first sniff… but actually I think in this particular use case it makes sense.

    I have an index (StringMap) of similar objects (all subtypes of a common base class).  Inserting objects into the index is easy because subtypes automatically get ‘cast’ to their base class.  Even then, I have some subtypes that require a bit of special treatment when added to the index, which I can do by overloading the Add() method.  Most of the time, all members of this index can be called via virtual methods (indeed I often iterate over the list, calling the virtual methods).

    But occasionally, I want to be able to use the extra (non-virtual) methods available in the subtypes from within more specialised code.  This is rare enough that I don’t want to bump up that functionality into the base class.

    In reality, all I am trying to do is save a little bit of typing during assignment :

    Local thing:Derived
    thing = Cast<Derived>(GetFromIndex(id))

    or

    Local thing:Derived
    thing = GetDerivedFromIndex(id)

    can be more succinctly written as :

    Local thing:Derived
    thing = GetFromIndex(id)

    But the latter requires an implicit cast (which I am trying to squeeze into an Operator To method).

    Another way to look at it is that downcasting in an Operator To method when fetching items from the index seems to me to be a direct analogue to overloading the Add() methods for inserting items.

    I think for now I am going to go the route of using GetDerivedFromIndex() methods, as this also allows me to do some type checking before doing a cast, which is not possible using an explicit cast.

    #11673

    ImmutableOctet
    Participant

    Have you tried using generic methods, and making ‘GetFromIndex’ take ‘Derived’ as an argument?

    Then you can have ‘GetFromIndex’ perform a cast to T, where T is ‘Derived’ in this case.

    #11684

    arpie
    Participant

    That would probably work, too but I think it will still be a bit clumsy.  I’ll keep playing around.  I really need to stop getting hung up on programming constructs and actually get on with writing a game 🙂

Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.