Only for nietod(question)

Posted on 2000-02-24
Last Modified: 2010-04-02
nietod,would you please tell me what's the difference between
const_cast<> static_cast<> and something like this way,using a parenthese before to cast:
int i=30;
char s=(char)i;

would you please give me some examples?
Question by:ASH
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
LVL 22

Accepted Solution

nietod earned 200 total points
ID: 2555610
const_cast can be used ONLY to remove const from something (also can remove volatile)   Unlike the other casts it cannot be used to change type (for the most part, more on that at the end).  For example,

const int i = 5
const int *ConstPtr = &i;
int *NonCostPtr = const_cast<int *>(ConstPtr); // okay.
char *CharPtr1 = const_cast<char *>(ConstPtr); // Error
char *ChaPtr2 = (char *)ConstPtr; // Okay--dangerious.

See how the first const_cast allows you to create a pointer to non constant from a pointer to a constant.  it removes constant.

In the 2nd example, it also tries to convert from int* to char *.  Constant cast cannot be used to convert betwen unrelated data types, so this does not work.  This can be usefule as it catches errors where you mistakenly try to convert a pointer between unrelated data types.

In the 3rd example, a C-style cast is used to conbert the int * to char *.  this succeeds where constant cast fails.  So a C-style cast is more powerful, but more dangerious, because it allows you to perform conversions that may not be safe.

(Actually removing const may not be safe, you have to be careful with that too, but changing data types is even more risky and const_cast allows you to be protected against code that accidentally does that.)

const_class does allows some data types conversions.  it does allow you to do conversions that can be done automatically, like the conversion from a derived class to a base class, so for example

const derived *DPtr;
base *BPtr = const_cast<base *>(DPtr);

is legal.

LVL 22

Expert Comment

ID: 2555669
static_cast is similar to the C-style cast, but slightly less powerful.  It cannot be used to cast away const (like the C-style cast did in the first set of conversions).  It also cannot be used to convert between completely unrelated types.  For example, it cannot convert int* to char* (like C-style did).  However it can be used to convert between related data types.  For example, it can be used to convert from a derived class to a base class--which is no surprise--that can be done automatically, and it can be used to convert from a base class to a derived class, which cannot be done automatically (i.e. without some sort of cast).  For this reason static_cast is most often used for downcasting, that is, for converting from a base class to one of its derived classes.  Now thi conversion is done based on the types used in the cast expression, not on any run time information, so the cast can be dangerious.  That is, it can be used to generate a pointer whose types is a pointer to a derived class even though it actually points to a base class, for example

class B
class D : public B

B Bas;
B *BPtr = &Bas;
D *DPtr = static_cast<D *>(BPtr);

The DPtr is initalized to point to Bas.  It is a D* pointer so it allows you to treat B as a D, even though it is not a D, it is a B.

static_cast cannot be used to cast away const and it cannot be used to convert between unrelated types.  So it is safer than a C-style cast.  i.e. it prevents you from accidentally making those sorts of conversions.  However, It does allow you to cast from base to derived when that sort of cast is incorrect though.  (same with C-style).

LVL 22

Expert Comment

ID: 2555707
dynamic_cast is similar to static cast.  it can be used for the same things (conversion between related types) and cannot be used for the same things (removing const, conversion between unrelated types).  The difference is that dynamic cast (when possible) performs the conversion at run-time, not compile time and performs the conversion based on the actually type of the object, not the source type in the expression.  So for example, in the code above where the static cast successfully converted from a pointer to a B object to a pointer to a D object, the dynamic_cast would detect that the object was really a B, not a D and would return a NULL pointer  (if done with references, rather than pointers it throws an exception when an error like this is detected.)  so for example

class B
   virtual ~B() {};
class D : public B

B Bas;
D Drv;
B *BPtr1 = &Bas;
B *BPtr2 = &Drv;
D *DPtr` = dynamic_cast<D *>(BPtr1);  // DPtr1 set to NULL;
D *DPtr2 = dynamic_cast<D *>(BPtr2); // DPtr2 set to Drv;

Note that both Bptr1 and BPtr2 have the same type, pointer to a B.  But while BPtr 1 actually points to a B, BPtr2 actually points to a D.  Okay?  Now in the two casts, the compiler has the same information, its sees a downcast from B* to D* which is sometimes legal and sometimes not.  In the first case it detects that the object is actually a B so it doesn't perform the conversion. In the 2nd cast it detects the object is really a D, so it does do the conversion.

Now the "detection of the true types" is possible only if the object contains a virtual function or a virtual base class.  If that is true, the conversion is done dynamically based on the actuall type at run-time.  If that is not true, then the conversion is done at compile type exactly the same as static_cast.

The last type of cast is reinterpret_cast.  Basicaly this is the C-style cast using the new syntax.  It can convert between unrelated types.  Like it can convert any pointer type to any other pointer type (even if the type types are not related.).
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 2556960
hmmm,great explanation:)
One makeup:
virtual base class is for mutil-inheritance to prevent ambiguity.
If two classes both derive from the same base class,and now you derive another one from it.Then it will make ambiguity sometimes:

class Root


class DerivedOne : public Root
class DerivedTwo : public Root

class Final : public DerivedOne, DerivedTwo

now ,if you have a Final instance and want to upcast it to Root.You will fail because there are two Root(two root address).
The virtue base class is to prevent this:

class DerivedOne : public virtual Root {};
class DerivedTwo : public virtual Root {};

This will make Final has one Root object and you can use it as Root.


LVL 22

Expert Comment

ID: 2557928
>> hmmm,great explanation:)
Thanks, but I thought it was kinda of "stream-of-consciousness".  its hard to write well under these circumstances..

I think you expanation missed one little important detail--the reason why you mention it.  The reason, which i touched on very briefly is that a compile time cast (static_cast, reinterpret_cast, C-style cast (even a const_class that convertes types)) might not safely convert for a derived class to a base class in a object that has virtual base clases.  The conversion will be okay if the the object is actually of the source type in the cast expression.  But if the object is really of a type derived from this specified source type, then the cast coudl be performed incorrectly.  i.e

class B {};
class D1 : public virtual B {};
class D2 : public D1 {};

D2 Drv;
D1 D1Ptr = &Drv;
B*BPtr = static_cast<B *>(D1Ptr);

the soucce type is supposed to be a D1, but the object is actually a D2, so this cast might not work correctly.  (Actually, it probably will in this case, but there is no guarantee.)

For this type of situation you must use a dynamic_cast.  It will examine the actual object and figure out how to make the conversion.

Author Comment

ID: 2558293
Adjusted points to 200

Author Comment

ID: 2558294
Dear Wyn, are you fine ?

Hi,nietod.I have increased the points for you excellent answer as Wyn suggest.
I will take a look now.

Author Comment

ID: 2558304
Thanks again.
Maybe I will need clarification later.

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

717 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question