CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Aug 2002
    Posts
    78

    static_cast vs. dynamic_cast and reinterpret_cast

    Let's suppose I have an array of a base class, but it's filled with derived classes. I'll use only one derived class, but suppose there are several types.

    Code:
    Edit: wrong! CBase myArray[MY_ARRAYSIZE];
    
    What I meant:  CBase *myArray[MY_ARRAYSIZE];
    
    ...
    
    reinterpret_cast<CDerived *>(myArray[i])->derivedFunction();

    According to the descriptions of the various castings, this is the wrong thing to do since it doesn't "climb the trees" to return the correct pointer (where a pointer to the derived might actually != pointer to the same object's base!)

    So I'd want to use dynamic_cast or static_cast instead (static_cast would be good enough for this particular application.)


    More importantly, reinterpret_cast is wrong to use in this situation always?
    Last edited by Gorgor; April 16th, 2004 at 09:03 AM.

  2. #2
    Join Date
    Aug 2002
    Posts
    78
    And as a follow up, as a practical matter, if you don't use multiple inheritence, will the results of reinterpret_cast and static/dynamic_cast ever differ on various compilers? I.e. will the base pointer always == the derived pointer?

  3. #3
    Join Date
    Feb 2003
    Posts
    377

    Re: static_cast vs. dynamic_cast and reinterpret_cast

    Originally posted by Gorgor
    Code:
    CBase myArray[MY_ARRAYSIZE];
    That doesn't make sense. If you have an array of base class objects, then they are base class objects and not derived class objects. Since the derived class generally will be larger in size than the base class, there's no way you could be putting derived class objects into the array that your compiler created full of base class objects.

    If you want an array of base class objects whose type is actually of a derived class, you'd need an array of pointers to base, and then you could use the dynamic_cast to get the appropriate derived object later:
    Code:
    CBase* myArray[MY_ARRAYSIZE];
    for (int i = 0; i < MY_ARRAYSIZE; i++)
        myArray[i] = new CDerived;
    
    // ...
    
    CDerived* myDerivedPtr = dynamic_cast<CDerived*>(myArray[j]);
    if (myDerivedPtr)
        myDerivedPtr->DerivedFunction();

  4. #4
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863
    Why don't you use polymorphism? This is what it is for.
    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

  5. #5
    Join Date
    Feb 2004
    Location
    USA - Florida
    Posts
    729
    It's not a good idea to store derived class objects in an array of the type base class since that will truncate (or slice-off) the derived class object's information. You'll need to store pointers-to-objects instead of actual objects as jlou as posted in the example code. However, dynamic_cast only succeeds if there is at least one function declared as virtual (it's sometimes called a "polymorphic cast").
    Hungarian notation, reinterpreted? http://www.joelonsoftware.com/articles/Wrong.html

  6. #6
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128
    In addition to jiou's and cma's suggestions, RTTI needs to be enable in order to use dynamic_cast.

  7. #7
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863
    And in addition to all of this RTTI talk, if you are casting pointers
    strored in a container of base class pointers, then you might have
    a bad design on your hands.
    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

  8. #8
    Join Date
    Mar 2004
    Location
    Israel
    Posts
    638
    in addition to what have been said,

    Scott Meyers, in his book "More Effective C++" warns of
    treating arrays polymorphically.
    Polymorphism and pointer arithmetic don't mix and since
    array operations almost always involve pointer arithmetic -
    you should avoid mixing the two.
    **** **** **** **** **/**

  9. #9
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    And in addition and for completeness...the following FAQ might help as well...

  10. #10
    Join Date
    Aug 2002
    Posts
    78
    I, of course, made a mistake in my posting. The array I meant to be an array of pointers to base, not of the base class itself.

    Code:
    CBase *myArray[blah];

    Having said that, and having read the FAQ, I still am looking for an answer. Apparently the return value of an up or downcast from base (pointer) to derived (pointer) or back might yield (properly done) different pointers.

    1. Hence, reinterpret_cast is the wrong thing to use to up or downcast. It always returns just the numerical pointer value, and appears to just be a syntax appeaser for the compiler.

    2. Static_cast will do this properly for the up (to base) cast, and also properly for the downcast, if the object is actually a derived class. If the object wasn't, you'd get a pointer as if it were, but this might be very bad.

    3. RTTI is not an option. This is an embedded product. Therefore dynamic_cast is not an option.

    4. In practice and in actual implementation in compilers, if the object does not have multiple inheritence, will the downcasted pointer returned ever actually differ from the upcast, base class pointer? (Or for that matter, actually modify contents in some kind of conversion?)
    Last edited by Gorgor; April 16th, 2004 at 04:12 PM.

  11. #11
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128
    Originally posted by Gorgor
    4. In practice and in actual implementation in compilers, if the object does not have multiple inheritence, will the downcasted pointer returned ever actually differ from the upcast, base class pointer? (Or for that matter, actually modify contents in some kind of conversion?)
    Not very sure what you mean exactly. Actually, a pointer is usually a 4-byte container that holds the address to an object. Not matter whether you upcast or downcast, the address it is holding, is always the same. The only different is the behavior of the pointer. When it is upcasted, the pointer only allow access to its public members, including public virtual function which is provided by the derived class. However, when it is downcasted, you are allow to access all public members of the base class and also the public members of the derived class as well.

    Hope this helps.

  12. #12
    Join Date
    Aug 2002
    Posts
    78
    I was sure I had read somewhere that casting such objects to other objects in their heirarchy could change the actual pointer value.

    If that is not the case, then how does static_cast differ from reinterpret_cast with respect to pointers to objects?

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449
    I suggest geting the standard and reading sections 5.2.9 (static_cast), and 5.2.10 (reinterpret_cast). They go into a lot of detail as to the differences between the two.

    One difference is that static_cast will perform conversions of one type to another using the standard conversion operators for the type being converted to, while reinterpret_cast does not.

    Regards,

    Paul McKenzie

  14. #14
    Join Date
    Aug 2002
    Posts
    78
    So reinterpret_cast is just a syntax appeaser, telling the compiler to think of this pointer as a pointer to x rather than a pointer to y.

    But how would that ever differ from static_cast if both always properly access member functions of base or derived? Descriptions I read are like lawyer talk, they blather a lot without ever saying much. "Reinterpret_cast" is only safe to use for casting back to what it originally was??? WTH is it good for then, other than casting a void pointer passed through some kind of generic callback?


    By strict interpretation, I presume my question is that reinterpret_cast is fine, since we are using a pointer that is to base to coerce back to pointer to derived, which we know it actually is. Is that the final answer?

  15. #15
    Join Date
    Jan 2001
    Posts
    253
    When using Multiple inheritance, the locations of sub objects are different. Using reinterpret_cast will not change the pointer value, so the result will be that the code will access the wrong part of the object.

    John

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured