anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

C++CASTING (4481B)

      1 C++-style Casting
      2 =================
      3 
      4 In C, you can cast in one of two ways:
      5 
      6 (type)var
      7 type(var)
      8 
      9 The problem with C-style casting is that it allows a programmer to get away
     10 with too much, and is also not designed to handle C++ classes.
     11 
     12 C++ has 4 types of casting in addition to allowing C-style casting.  They are:
     13 
     14 static_cast
     15 const_cast
     16 dynamic_cast
     17 reinterpret_cast
     18 
     19 The syntax is usually *_cast<type>(var).
     20 
     21 static_cast
     22 -----------
     23 
     24 From my experience, this cast is closest to C-style casting for non-pointer
     25 types as well as between some (but not all) pointer types.  This type of cast,
     26 like C-style casting, is performed at compile-time.  static_cast can also do
     27 a downcast of a derived class to a base class, but only if the base class is
     28 not a virtual base class.  Sometimes the result of this cast can become
     29 undefined.  static_cast is a bit more strict that C-style casting, though.  It
     30 disallows certain class conversions that would've been allowed with a C-style
     31 cast.  static_cast also doesn't allow you to cast to an incomplete type.  In
     32 these cases, I would try either dynamic_cast or reinterpret_cast.
     33 
     34 const_cast
     35 ----------
     36 
     37 This cast is mainly to add or remove const-ness or volatile-ness from a
     38 variable.  This is safer than using a C-style cast to change the const-ness
     39 of a variable.  In most cases if you try to use one of the other casts and it
     40 complains about const-ness, you will want to either use this cast instead or
     41 wrap the other cast around this cast.  An example:
     42 
     43 const int *a;
     44 static_cast<void *>(a); <-- This will fail.
     45 
     46 To remedy the above, you would might try this:
     47 
     48 const int *a;
     49 const_cast<void *>(a); <-- But this will still fail.
     50 
     51 The real solution is this:
     52 
     53 const int *a;
     54 static_cast<void *>(const_cast<int *>(a));
     55 
     56 It is not recommended to use const_cast on the this variable within a member
     57 function of a class that is declared const.  Instead you should use the mutable
     58 keyword on the variable in the class's definition.
     59 
     60 dynamic_cast
     61 ------------
     62 
     63 This cast can only be used on pointers or references to classes.  It can cast a
     64 derived class to a base class, a derived class to another derived class
     65 (provided that both are children of the same base class), or a base class to a
     66 derived class.  You can also use this to cast a class to void *.  This cast is
     67 done at run-time as opposed to the other casts, and relies on C++'s RTTI to be
     68 enabled.  It is meant to be used on polymorphic classes, so use static_cast on
     69 non-polymorphic classes.
     70 
     71 derived-to-base conversions are actually done statically, so you use either
     72 dynamic_cast or static_cast on them, regardless of if the classes are
     73 polymorphic or not.
     74 
     75 derived-to-derived or base-to-derived conversions, however, rely on run-time
     76 type information, and this cast is used on those classes that are polymorphic.
     77 This is safer than C-style casting in that an invalid pointer conversion will
     78 return a NULL pointer, and an invalid reference conversion will throw a
     79 Bad_cast exception.
     80 
     81 Note that in Anope we prefer if Anope::debug_cast is used.
     82 This uses dynamic_cast (and checks for a NULL pointer return) on debug builds
     83 and static_cast on release builds, to speed up the program because of dynamic_cast's
     84 reliance on RTTI.
     85 
     86 reinterpret_cast
     87 ----------------
     88 
     89 This cast I would use only as a last resort if static_cast isn't allowed on a
     90 conversion.  It allows for conversions between two unrelated types, such as
     91 going from char * to int *.  It can also be used to convert a pointer to an
     92 integral type and vica versa.  The sites I've read mention how the result is
     93 non-portable, which I assume means the resulting object code is non-portable,
     94 so since the code is compiled on many systems anyways, I don't see this as
     95 being a huge issue.  It is recommended to only use this if necessary, though.
     96 
     97 Links
     98 =====
     99 
    100 The following links are web sites I've used to get this information, and might
    101 describe some of the above a bit better than I have. :P
    102 
    103 https://www.acm.org/crossroads/xrds3-1/ovp3-1.html
    104 http://www.cplusplus.com/doc/tutorial/typecasting.html
    105 http://www.codeguru.com/forum/showthread.php?t=312456
    106 https://web.archive.org/web/20170810222238/http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/cast.html
    107 https://www.microsoft.com/en-us/download/details.aspx?id=55984
    108 https://en.wikibooks.org/wiki/C%2B%2B_Programming/Type_Casting
    109 https://web.archive.org/web/20160510114447/http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=134
    110 
    111 -- CyberBotX, Nov 23, 2008