Related
This question already has answers here:
When should static_cast, dynamic_cast, const_cast, and reinterpret_cast be used?
(11 answers)
Closed 8 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
I've been writing C and C++ code for almost twenty years, but there's one aspect of these languages that I've never really understood. I've obviously used regular casts i.e.
MyClass *m = (MyClass *)ptr;
all over the place, but there seem to be two other types of casts, and I don't know the difference. What's the difference between the following lines of code?
MyClass *m = (MyClass *)ptr;
MyClass *m = static_cast<MyClass *>(ptr);
MyClass *m = dynamic_cast<MyClass *>(ptr);
static_cast
static_cast is used for cases where you basically want to reverse an implicit conversion, with a few restrictions and additions. static_cast performs no runtime checks. This should be used if you know that you refer to an object of a specific type, and thus a check would be unnecessary. Example:
void func(void *data) {
// Conversion from MyClass* -> void* is implicit
MyClass *c = static_cast<MyClass*>(data);
...
}
int main() {
MyClass c;
start_thread(&func, &c) // func(&c) will be called
.join();
}
In this example, you know that you passed a MyClass object, and thus there isn't any need for a runtime check to ensure this.
dynamic_cast
dynamic_cast is useful when you don't know what the dynamic type of the object is. It returns a null pointer if the object referred to doesn't contain the type casted to as a base class (when you cast to a reference, a bad_cast exception is thrown in that case).
if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) {
...
} else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
...
}
You can not use dynamic_cast for downcast (casting to a derived class) if the argument type is not polymorphic. For example, the following code is not valid, because Base doesn't contain any virtual function:
struct Base { };
struct Derived : Base { };
int main() {
Derived d; Base *b = &d;
dynamic_cast<Derived*>(b); // Invalid
}
An "up-cast" (cast to the base class) is always valid with both static_cast and dynamic_cast, and also without any cast, as an "up-cast" is an implicit conversion (assuming the base class is accessible, i.e. it's a public inheritance).
Regular Cast
These casts are also called C-style cast. A C-style cast is basically identical to trying out a range of sequences of C++ casts, and taking the first C++ cast that works, without ever considering dynamic_cast. Needless to say, this is much more powerful as it combines all of const_cast, static_cast and reinterpret_cast, but it's also unsafe, because it does not use dynamic_cast.
In addition, C-style casts not only allow you to do this, but they also allow you to safely cast to a private base-class, while the "equivalent" static_cast sequence would give you a compile-time error for that.
Some people prefer C-style casts because of their brevity. I use them for numeric casts only, and use the appropriate C++ casts when user defined types are involved, as they provide stricter checking.
Static cast
The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.
*p = 5; // run-time error: stack corruption
In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.
int *q = static_cast<int*>(&c); // compile-time error
Reinterpret cast
To force the pointer conversion, in the same way as the C-style cast does in the background, the reinterpret cast would be used instead.
int *r = reinterpret_cast<int*>(&c); // forced conversion
This cast handles conversions between certain unrelated types, such as from one pointer type to another incompatible pointer type. It will simply perform a binary copy of the data without altering the underlying bit pattern. Note that the result of such a low-level operation is system-specific and therefore not portable. It should be used with caution if it cannot be avoided altogether.
Dynamic cast
This one is only used to convert object pointers and object references into other pointer or reference types in the inheritance hierarchy. It is the only cast that makes sure that the object pointed to can be converted, by performing a run-time check that the pointer refers to a complete object of the destination type. For this run-time check to be possible the object must be polymorphic. That is, the class must define or inherit at least one virtual function. This is because the compiler will only generate the needed run-time type information for such objects.
Dynamic cast examples
In the example below, a MyChild pointer is converted into a MyBase pointer using a dynamic cast. This derived-to-base conversion succeeds, because the Child object includes a complete Base object.
class MyBase
{
public:
virtual void test() {}
};
class MyChild : public MyBase {};
int main()
{
MyChild *child = new MyChild();
MyBase *base = dynamic_cast<MyBase*>(child); // ok
}
The next example attempts to convert a MyBase pointer to a MyChild pointer. Since the Base object does not contain a complete Child object this pointer conversion will fail. To indicate this, the dynamic cast returns a null pointer. This gives a convenient way to check whether or not a conversion has succeeded during run-time.
MyBase *base = new MyBase();
MyChild *child = dynamic_cast<MyChild*>(base);
if (child == 0)
std::cout << "Null pointer returned";
If a reference is converted instead of a pointer, the dynamic cast will then fail by throwing a bad_cast exception. This needs to be handled using a try-catch statement.
#include <exception>
// …
try
{
MyChild &child = dynamic_cast<MyChild&>(*base);
}
catch(std::bad_cast &e)
{
std::cout << e.what(); // bad dynamic_cast
}
Dynamic or static cast
The advantage of using a dynamic cast is that it allows the programmer to check whether or not a conversion has succeeded during run-time. The disadvantage is that there is a performance overhead associated with doing this check. For this reason using a static cast would have been preferable in the first example, because a derived-to-base conversion will never fail.
MyBase *base = static_cast<MyBase*>(child); // ok
However, in the second example the conversion may either succeed or fail. It will fail if the MyBase object contains a MyBase instance and it will succeed if it contains a MyChild instance. In some situations this may not be known until run-time. When this is the case dynamic cast is a better choice than static cast.
// Succeeds for a MyChild object
MyChild *child = dynamic_cast<MyChild*>(base);
If the base-to-derived conversion had been performed using a static cast instead of a dynamic cast the conversion would not have failed. It would have returned a pointer that referred to an incomplete object. Dereferencing such a pointer can lead to run-time errors.
// Allowed, but invalid
MyChild *child = static_cast<MyChild*>(base);
// Incomplete MyChild object dereferenced
(*child);
Const cast
This one is primarily used to add or remove the const modifier of a variable.
const int myConst = 5;
int *nonConst = const_cast<int*>(&myConst); // removes const
Although const cast allows the value of a constant to be changed, doing so is still invalid code that may cause a run-time error. This could occur for example if the constant was located in a section of read-only memory.
*nonConst = 10; // potential run-time error
const cast is instead used mainly when there is a function that takes a non-constant pointer argument, even though it does not modify the pointee.
void print(int *p)
{
std::cout << *p;
}
The function can then be passed a constant variable by using a const cast.
print(&myConst); // error: cannot convert
// const int* to int*
print(nonConst); // allowed
Source and More Explanations
You should look at the article C++ Programming/Type Casting.
It contains a good description of all of the different cast types. The following taken from the above link:
const_cast
const_cast(expression) The const_cast<>() is used to add/remove
const(ness) (or volatile-ness) of a variable.
static_cast
static_cast(expression) The static_cast<>() is used to cast between
the integer types. 'e.g.' char->long, int->short etc.
Static cast is also used to cast pointers to related types, for
example casting void* to the appropriate type.
dynamic_cast
Dynamic cast is used to convert pointers and references at run-time,
generally for the purpose of casting a pointer or reference up or down
an inheritance chain (inheritance hierarchy).
dynamic_cast(expression)
The target type must be a pointer or reference type, and the
expression must evaluate to a pointer or reference. Dynamic cast works
only when the type of object to which the expression refers is
compatible with the target type and the base class has at least one
virtual member function. If not, and the type of expression being cast
is a pointer, NULL is returned, if a dynamic cast on a reference
fails, a bad_cast exception is thrown. When it doesn't fail, dynamic
cast returns a pointer or reference of the target type to the object
to which expression referred.
reinterpret_cast
Reinterpret cast simply casts one type bitwise to another. Any pointer
or integral type can be casted to any other with reinterpret cast,
easily allowing for misuse. For instance, with reinterpret cast one
might, unsafely, cast an integer pointer to a string pointer.
FYI, I believe Bjarne Stroustrup is quoted as saying that C-style casts are to be avoided and that you should use static_cast or dynamic_cast if at all possible.
Barne Stroustrup's C++ style FAQ
Take that advice for what you will. I'm far from being a C++ guru.
Avoid using C-Style casts.
C-style casts are a mix of const and reinterpret cast, and it's difficult to find-and-replace in your code. A C++ application programmer should avoid C-style cast.
C-style casts conflate const_cast, static_cast, and reinterpret_cast.
I wish C++ didn't have C-style casts. C++ casts stand out properly (as they should; casts are normally indicative of doing something bad) and properly distinguish between the different kinds of conversion that casts perform. They also permit similar-looking functions to be written, e.g. boost::lexical_cast, which is quite nice from a consistency perspective.
dynamic_cast has runtime type checking and only works with references and pointers, whereas static_cast does not offer runtime type checking. For complete information, see the MSDN article static_cast Operator.
dynamic_cast only supports pointer and reference types. It returns NULL if the cast is impossible if the type is a pointer or throws an exception if the type is a reference type. Hence, dynamic_cast can be used to check if an object is of a given type, static_cast cannot (you will simply end up with an invalid value).
C-style (and other) casts have been covered in the other answers.
I'm facing some issues while using exception handling for dynamic_cast. It is not returning bad_cast always.
the statement below is not throwing me bad_cast, though d1 is returned nullptr and compiler is showing me warning
derived *d1 = dynamic_cast <derived *> (&base);
but if i try with following statement:
derived d1 = dynamic_cast <derived &> (base);
then it will throw std::bad_cast
Am I missing something in the logic? classes are polymorphic.
This is defined that way.
If the new type to be casted to is a pointer the result is a nullptr on error.
If it is a reference it throws an exception.
See http://en.cppreference.com/w/cpp/language/dynamic_cast
If the cast is successful, dynamic_cast returns a value of type new_type. If the cast fails and new_type is a pointer type, it returns a null pointer of that type. If the cast fails and new_type is a reference type, it throws an exception that matches a handler of type std::bad_cast.
As already answered, this is the defined behavior.
the logic behind this is that when the developer asks the program to convert pointer to another type pointer, you can return null as a valid failure result.
but you can't do it with references. there is no such thing as "null reference" nor can you construct "default reference" and pass it by reference to dynamic_cast (as an "out" parameter). basically, if you can't convert a reference to another type of reference, you don't have much to do other than throwing an exception. any other "failure techniques" (such as returning bool , error code, null pointers etc.) cannot work with references.
As a side note, I myself used dynamic_cast in my works yet I'm not proud of it it at all. for me, the use of dynamic_cast was some sort of defensive programming. usually, If you hold a pointer or a reference to a base class, it makes more sense to use virtual functions to handle derived-class behavior then explicitly go through the pain of manual casing.
This is the expected behavior of dynamic_cast.
If the cast fails and new_type is a pointer type, it returns a null pointer of that type. If the cast fails and new_type is a reference type, it throws an exception that matches a handler of type std::bad_cast.
This question already has answers here:
When should static_cast, dynamic_cast, const_cast, and reinterpret_cast be used?
(11 answers)
Closed 8 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
I've been writing C and C++ code for almost twenty years, but there's one aspect of these languages that I've never really understood. I've obviously used regular casts i.e.
MyClass *m = (MyClass *)ptr;
all over the place, but there seem to be two other types of casts, and I don't know the difference. What's the difference between the following lines of code?
MyClass *m = (MyClass *)ptr;
MyClass *m = static_cast<MyClass *>(ptr);
MyClass *m = dynamic_cast<MyClass *>(ptr);
static_cast
static_cast is used for cases where you basically want to reverse an implicit conversion, with a few restrictions and additions. static_cast performs no runtime checks. This should be used if you know that you refer to an object of a specific type, and thus a check would be unnecessary. Example:
void func(void *data) {
// Conversion from MyClass* -> void* is implicit
MyClass *c = static_cast<MyClass*>(data);
...
}
int main() {
MyClass c;
start_thread(&func, &c) // func(&c) will be called
.join();
}
In this example, you know that you passed a MyClass object, and thus there isn't any need for a runtime check to ensure this.
dynamic_cast
dynamic_cast is useful when you don't know what the dynamic type of the object is. It returns a null pointer if the object referred to doesn't contain the type casted to as a base class (when you cast to a reference, a bad_cast exception is thrown in that case).
if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) {
...
} else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
...
}
You can not use dynamic_cast for downcast (casting to a derived class) if the argument type is not polymorphic. For example, the following code is not valid, because Base doesn't contain any virtual function:
struct Base { };
struct Derived : Base { };
int main() {
Derived d; Base *b = &d;
dynamic_cast<Derived*>(b); // Invalid
}
An "up-cast" (cast to the base class) is always valid with both static_cast and dynamic_cast, and also without any cast, as an "up-cast" is an implicit conversion (assuming the base class is accessible, i.e. it's a public inheritance).
Regular Cast
These casts are also called C-style cast. A C-style cast is basically identical to trying out a range of sequences of C++ casts, and taking the first C++ cast that works, without ever considering dynamic_cast. Needless to say, this is much more powerful as it combines all of const_cast, static_cast and reinterpret_cast, but it's also unsafe, because it does not use dynamic_cast.
In addition, C-style casts not only allow you to do this, but they also allow you to safely cast to a private base-class, while the "equivalent" static_cast sequence would give you a compile-time error for that.
Some people prefer C-style casts because of their brevity. I use them for numeric casts only, and use the appropriate C++ casts when user defined types are involved, as they provide stricter checking.
Static cast
The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.
*p = 5; // run-time error: stack corruption
In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.
int *q = static_cast<int*>(&c); // compile-time error
Reinterpret cast
To force the pointer conversion, in the same way as the C-style cast does in the background, the reinterpret cast would be used instead.
int *r = reinterpret_cast<int*>(&c); // forced conversion
This cast handles conversions between certain unrelated types, such as from one pointer type to another incompatible pointer type. It will simply perform a binary copy of the data without altering the underlying bit pattern. Note that the result of such a low-level operation is system-specific and therefore not portable. It should be used with caution if it cannot be avoided altogether.
Dynamic cast
This one is only used to convert object pointers and object references into other pointer or reference types in the inheritance hierarchy. It is the only cast that makes sure that the object pointed to can be converted, by performing a run-time check that the pointer refers to a complete object of the destination type. For this run-time check to be possible the object must be polymorphic. That is, the class must define or inherit at least one virtual function. This is because the compiler will only generate the needed run-time type information for such objects.
Dynamic cast examples
In the example below, a MyChild pointer is converted into a MyBase pointer using a dynamic cast. This derived-to-base conversion succeeds, because the Child object includes a complete Base object.
class MyBase
{
public:
virtual void test() {}
};
class MyChild : public MyBase {};
int main()
{
MyChild *child = new MyChild();
MyBase *base = dynamic_cast<MyBase*>(child); // ok
}
The next example attempts to convert a MyBase pointer to a MyChild pointer. Since the Base object does not contain a complete Child object this pointer conversion will fail. To indicate this, the dynamic cast returns a null pointer. This gives a convenient way to check whether or not a conversion has succeeded during run-time.
MyBase *base = new MyBase();
MyChild *child = dynamic_cast<MyChild*>(base);
if (child == 0)
std::cout << "Null pointer returned";
If a reference is converted instead of a pointer, the dynamic cast will then fail by throwing a bad_cast exception. This needs to be handled using a try-catch statement.
#include <exception>
// …
try
{
MyChild &child = dynamic_cast<MyChild&>(*base);
}
catch(std::bad_cast &e)
{
std::cout << e.what(); // bad dynamic_cast
}
Dynamic or static cast
The advantage of using a dynamic cast is that it allows the programmer to check whether or not a conversion has succeeded during run-time. The disadvantage is that there is a performance overhead associated with doing this check. For this reason using a static cast would have been preferable in the first example, because a derived-to-base conversion will never fail.
MyBase *base = static_cast<MyBase*>(child); // ok
However, in the second example the conversion may either succeed or fail. It will fail if the MyBase object contains a MyBase instance and it will succeed if it contains a MyChild instance. In some situations this may not be known until run-time. When this is the case dynamic cast is a better choice than static cast.
// Succeeds for a MyChild object
MyChild *child = dynamic_cast<MyChild*>(base);
If the base-to-derived conversion had been performed using a static cast instead of a dynamic cast the conversion would not have failed. It would have returned a pointer that referred to an incomplete object. Dereferencing such a pointer can lead to run-time errors.
// Allowed, but invalid
MyChild *child = static_cast<MyChild*>(base);
// Incomplete MyChild object dereferenced
(*child);
Const cast
This one is primarily used to add or remove the const modifier of a variable.
const int myConst = 5;
int *nonConst = const_cast<int*>(&myConst); // removes const
Although const cast allows the value of a constant to be changed, doing so is still invalid code that may cause a run-time error. This could occur for example if the constant was located in a section of read-only memory.
*nonConst = 10; // potential run-time error
const cast is instead used mainly when there is a function that takes a non-constant pointer argument, even though it does not modify the pointee.
void print(int *p)
{
std::cout << *p;
}
The function can then be passed a constant variable by using a const cast.
print(&myConst); // error: cannot convert
// const int* to int*
print(nonConst); // allowed
Source and More Explanations
You should look at the article C++ Programming/Type Casting.
It contains a good description of all of the different cast types. The following taken from the above link:
const_cast
const_cast(expression) The const_cast<>() is used to add/remove
const(ness) (or volatile-ness) of a variable.
static_cast
static_cast(expression) The static_cast<>() is used to cast between
the integer types. 'e.g.' char->long, int->short etc.
Static cast is also used to cast pointers to related types, for
example casting void* to the appropriate type.
dynamic_cast
Dynamic cast is used to convert pointers and references at run-time,
generally for the purpose of casting a pointer or reference up or down
an inheritance chain (inheritance hierarchy).
dynamic_cast(expression)
The target type must be a pointer or reference type, and the
expression must evaluate to a pointer or reference. Dynamic cast works
only when the type of object to which the expression refers is
compatible with the target type and the base class has at least one
virtual member function. If not, and the type of expression being cast
is a pointer, NULL is returned, if a dynamic cast on a reference
fails, a bad_cast exception is thrown. When it doesn't fail, dynamic
cast returns a pointer or reference of the target type to the object
to which expression referred.
reinterpret_cast
Reinterpret cast simply casts one type bitwise to another. Any pointer
or integral type can be casted to any other with reinterpret cast,
easily allowing for misuse. For instance, with reinterpret cast one
might, unsafely, cast an integer pointer to a string pointer.
FYI, I believe Bjarne Stroustrup is quoted as saying that C-style casts are to be avoided and that you should use static_cast or dynamic_cast if at all possible.
Barne Stroustrup's C++ style FAQ
Take that advice for what you will. I'm far from being a C++ guru.
Avoid using C-Style casts.
C-style casts are a mix of const and reinterpret cast, and it's difficult to find-and-replace in your code. A C++ application programmer should avoid C-style cast.
C-style casts conflate const_cast, static_cast, and reinterpret_cast.
I wish C++ didn't have C-style casts. C++ casts stand out properly (as they should; casts are normally indicative of doing something bad) and properly distinguish between the different kinds of conversion that casts perform. They also permit similar-looking functions to be written, e.g. boost::lexical_cast, which is quite nice from a consistency perspective.
dynamic_cast has runtime type checking and only works with references and pointers, whereas static_cast does not offer runtime type checking. For complete information, see the MSDN article static_cast Operator.
dynamic_cast only supports pointer and reference types. It returns NULL if the cast is impossible if the type is a pointer or throws an exception if the type is a reference type. Hence, dynamic_cast can be used to check if an object is of a given type, static_cast cannot (you will simply end up with an invalid value).
C-style (and other) casts have been covered in the other answers.
This question already has answers here:
When should static_cast, dynamic_cast, const_cast, and reinterpret_cast be used?
(11 answers)
Closed 8 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
I've been writing C and C++ code for almost twenty years, but there's one aspect of these languages that I've never really understood. I've obviously used regular casts i.e.
MyClass *m = (MyClass *)ptr;
all over the place, but there seem to be two other types of casts, and I don't know the difference. What's the difference between the following lines of code?
MyClass *m = (MyClass *)ptr;
MyClass *m = static_cast<MyClass *>(ptr);
MyClass *m = dynamic_cast<MyClass *>(ptr);
static_cast
static_cast is used for cases where you basically want to reverse an implicit conversion, with a few restrictions and additions. static_cast performs no runtime checks. This should be used if you know that you refer to an object of a specific type, and thus a check would be unnecessary. Example:
void func(void *data) {
// Conversion from MyClass* -> void* is implicit
MyClass *c = static_cast<MyClass*>(data);
...
}
int main() {
MyClass c;
start_thread(&func, &c) // func(&c) will be called
.join();
}
In this example, you know that you passed a MyClass object, and thus there isn't any need for a runtime check to ensure this.
dynamic_cast
dynamic_cast is useful when you don't know what the dynamic type of the object is. It returns a null pointer if the object referred to doesn't contain the type casted to as a base class (when you cast to a reference, a bad_cast exception is thrown in that case).
if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) {
...
} else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
...
}
You can not use dynamic_cast for downcast (casting to a derived class) if the argument type is not polymorphic. For example, the following code is not valid, because Base doesn't contain any virtual function:
struct Base { };
struct Derived : Base { };
int main() {
Derived d; Base *b = &d;
dynamic_cast<Derived*>(b); // Invalid
}
An "up-cast" (cast to the base class) is always valid with both static_cast and dynamic_cast, and also without any cast, as an "up-cast" is an implicit conversion (assuming the base class is accessible, i.e. it's a public inheritance).
Regular Cast
These casts are also called C-style cast. A C-style cast is basically identical to trying out a range of sequences of C++ casts, and taking the first C++ cast that works, without ever considering dynamic_cast. Needless to say, this is much more powerful as it combines all of const_cast, static_cast and reinterpret_cast, but it's also unsafe, because it does not use dynamic_cast.
In addition, C-style casts not only allow you to do this, but they also allow you to safely cast to a private base-class, while the "equivalent" static_cast sequence would give you a compile-time error for that.
Some people prefer C-style casts because of their brevity. I use them for numeric casts only, and use the appropriate C++ casts when user defined types are involved, as they provide stricter checking.
Static cast
The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.
*p = 5; // run-time error: stack corruption
In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.
int *q = static_cast<int*>(&c); // compile-time error
Reinterpret cast
To force the pointer conversion, in the same way as the C-style cast does in the background, the reinterpret cast would be used instead.
int *r = reinterpret_cast<int*>(&c); // forced conversion
This cast handles conversions between certain unrelated types, such as from one pointer type to another incompatible pointer type. It will simply perform a binary copy of the data without altering the underlying bit pattern. Note that the result of such a low-level operation is system-specific and therefore not portable. It should be used with caution if it cannot be avoided altogether.
Dynamic cast
This one is only used to convert object pointers and object references into other pointer or reference types in the inheritance hierarchy. It is the only cast that makes sure that the object pointed to can be converted, by performing a run-time check that the pointer refers to a complete object of the destination type. For this run-time check to be possible the object must be polymorphic. That is, the class must define or inherit at least one virtual function. This is because the compiler will only generate the needed run-time type information for such objects.
Dynamic cast examples
In the example below, a MyChild pointer is converted into a MyBase pointer using a dynamic cast. This derived-to-base conversion succeeds, because the Child object includes a complete Base object.
class MyBase
{
public:
virtual void test() {}
};
class MyChild : public MyBase {};
int main()
{
MyChild *child = new MyChild();
MyBase *base = dynamic_cast<MyBase*>(child); // ok
}
The next example attempts to convert a MyBase pointer to a MyChild pointer. Since the Base object does not contain a complete Child object this pointer conversion will fail. To indicate this, the dynamic cast returns a null pointer. This gives a convenient way to check whether or not a conversion has succeeded during run-time.
MyBase *base = new MyBase();
MyChild *child = dynamic_cast<MyChild*>(base);
if (child == 0)
std::cout << "Null pointer returned";
If a reference is converted instead of a pointer, the dynamic cast will then fail by throwing a bad_cast exception. This needs to be handled using a try-catch statement.
#include <exception>
// …
try
{
MyChild &child = dynamic_cast<MyChild&>(*base);
}
catch(std::bad_cast &e)
{
std::cout << e.what(); // bad dynamic_cast
}
Dynamic or static cast
The advantage of using a dynamic cast is that it allows the programmer to check whether or not a conversion has succeeded during run-time. The disadvantage is that there is a performance overhead associated with doing this check. For this reason using a static cast would have been preferable in the first example, because a derived-to-base conversion will never fail.
MyBase *base = static_cast<MyBase*>(child); // ok
However, in the second example the conversion may either succeed or fail. It will fail if the MyBase object contains a MyBase instance and it will succeed if it contains a MyChild instance. In some situations this may not be known until run-time. When this is the case dynamic cast is a better choice than static cast.
// Succeeds for a MyChild object
MyChild *child = dynamic_cast<MyChild*>(base);
If the base-to-derived conversion had been performed using a static cast instead of a dynamic cast the conversion would not have failed. It would have returned a pointer that referred to an incomplete object. Dereferencing such a pointer can lead to run-time errors.
// Allowed, but invalid
MyChild *child = static_cast<MyChild*>(base);
// Incomplete MyChild object dereferenced
(*child);
Const cast
This one is primarily used to add or remove the const modifier of a variable.
const int myConst = 5;
int *nonConst = const_cast<int*>(&myConst); // removes const
Although const cast allows the value of a constant to be changed, doing so is still invalid code that may cause a run-time error. This could occur for example if the constant was located in a section of read-only memory.
*nonConst = 10; // potential run-time error
const cast is instead used mainly when there is a function that takes a non-constant pointer argument, even though it does not modify the pointee.
void print(int *p)
{
std::cout << *p;
}
The function can then be passed a constant variable by using a const cast.
print(&myConst); // error: cannot convert
// const int* to int*
print(nonConst); // allowed
Source and More Explanations
You should look at the article C++ Programming/Type Casting.
It contains a good description of all of the different cast types. The following taken from the above link:
const_cast
const_cast(expression) The const_cast<>() is used to add/remove
const(ness) (or volatile-ness) of a variable.
static_cast
static_cast(expression) The static_cast<>() is used to cast between
the integer types. 'e.g.' char->long, int->short etc.
Static cast is also used to cast pointers to related types, for
example casting void* to the appropriate type.
dynamic_cast
Dynamic cast is used to convert pointers and references at run-time,
generally for the purpose of casting a pointer or reference up or down
an inheritance chain (inheritance hierarchy).
dynamic_cast(expression)
The target type must be a pointer or reference type, and the
expression must evaluate to a pointer or reference. Dynamic cast works
only when the type of object to which the expression refers is
compatible with the target type and the base class has at least one
virtual member function. If not, and the type of expression being cast
is a pointer, NULL is returned, if a dynamic cast on a reference
fails, a bad_cast exception is thrown. When it doesn't fail, dynamic
cast returns a pointer or reference of the target type to the object
to which expression referred.
reinterpret_cast
Reinterpret cast simply casts one type bitwise to another. Any pointer
or integral type can be casted to any other with reinterpret cast,
easily allowing for misuse. For instance, with reinterpret cast one
might, unsafely, cast an integer pointer to a string pointer.
FYI, I believe Bjarne Stroustrup is quoted as saying that C-style casts are to be avoided and that you should use static_cast or dynamic_cast if at all possible.
Barne Stroustrup's C++ style FAQ
Take that advice for what you will. I'm far from being a C++ guru.
Avoid using C-Style casts.
C-style casts are a mix of const and reinterpret cast, and it's difficult to find-and-replace in your code. A C++ application programmer should avoid C-style cast.
C-style casts conflate const_cast, static_cast, and reinterpret_cast.
I wish C++ didn't have C-style casts. C++ casts stand out properly (as they should; casts are normally indicative of doing something bad) and properly distinguish between the different kinds of conversion that casts perform. They also permit similar-looking functions to be written, e.g. boost::lexical_cast, which is quite nice from a consistency perspective.
dynamic_cast has runtime type checking and only works with references and pointers, whereas static_cast does not offer runtime type checking. For complete information, see the MSDN article static_cast Operator.
dynamic_cast only supports pointer and reference types. It returns NULL if the cast is impossible if the type is a pointer or throws an exception if the type is a reference type. Hence, dynamic_cast can be used to check if an object is of a given type, static_cast cannot (you will simply end up with an invalid value).
C-style (and other) casts have been covered in the other answers.
This question already has answers here:
When should static_cast, dynamic_cast, const_cast, and reinterpret_cast be used?
(11 answers)
Closed 8 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
I've been writing C and C++ code for almost twenty years, but there's one aspect of these languages that I've never really understood. I've obviously used regular casts i.e.
MyClass *m = (MyClass *)ptr;
all over the place, but there seem to be two other types of casts, and I don't know the difference. What's the difference between the following lines of code?
MyClass *m = (MyClass *)ptr;
MyClass *m = static_cast<MyClass *>(ptr);
MyClass *m = dynamic_cast<MyClass *>(ptr);
static_cast
static_cast is used for cases where you basically want to reverse an implicit conversion, with a few restrictions and additions. static_cast performs no runtime checks. This should be used if you know that you refer to an object of a specific type, and thus a check would be unnecessary. Example:
void func(void *data) {
// Conversion from MyClass* -> void* is implicit
MyClass *c = static_cast<MyClass*>(data);
...
}
int main() {
MyClass c;
start_thread(&func, &c) // func(&c) will be called
.join();
}
In this example, you know that you passed a MyClass object, and thus there isn't any need for a runtime check to ensure this.
dynamic_cast
dynamic_cast is useful when you don't know what the dynamic type of the object is. It returns a null pointer if the object referred to doesn't contain the type casted to as a base class (when you cast to a reference, a bad_cast exception is thrown in that case).
if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) {
...
} else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
...
}
You can not use dynamic_cast for downcast (casting to a derived class) if the argument type is not polymorphic. For example, the following code is not valid, because Base doesn't contain any virtual function:
struct Base { };
struct Derived : Base { };
int main() {
Derived d; Base *b = &d;
dynamic_cast<Derived*>(b); // Invalid
}
An "up-cast" (cast to the base class) is always valid with both static_cast and dynamic_cast, and also without any cast, as an "up-cast" is an implicit conversion (assuming the base class is accessible, i.e. it's a public inheritance).
Regular Cast
These casts are also called C-style cast. A C-style cast is basically identical to trying out a range of sequences of C++ casts, and taking the first C++ cast that works, without ever considering dynamic_cast. Needless to say, this is much more powerful as it combines all of const_cast, static_cast and reinterpret_cast, but it's also unsafe, because it does not use dynamic_cast.
In addition, C-style casts not only allow you to do this, but they also allow you to safely cast to a private base-class, while the "equivalent" static_cast sequence would give you a compile-time error for that.
Some people prefer C-style casts because of their brevity. I use them for numeric casts only, and use the appropriate C++ casts when user defined types are involved, as they provide stricter checking.
Static cast
The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.
*p = 5; // run-time error: stack corruption
In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.
int *q = static_cast<int*>(&c); // compile-time error
Reinterpret cast
To force the pointer conversion, in the same way as the C-style cast does in the background, the reinterpret cast would be used instead.
int *r = reinterpret_cast<int*>(&c); // forced conversion
This cast handles conversions between certain unrelated types, such as from one pointer type to another incompatible pointer type. It will simply perform a binary copy of the data without altering the underlying bit pattern. Note that the result of such a low-level operation is system-specific and therefore not portable. It should be used with caution if it cannot be avoided altogether.
Dynamic cast
This one is only used to convert object pointers and object references into other pointer or reference types in the inheritance hierarchy. It is the only cast that makes sure that the object pointed to can be converted, by performing a run-time check that the pointer refers to a complete object of the destination type. For this run-time check to be possible the object must be polymorphic. That is, the class must define or inherit at least one virtual function. This is because the compiler will only generate the needed run-time type information for such objects.
Dynamic cast examples
In the example below, a MyChild pointer is converted into a MyBase pointer using a dynamic cast. This derived-to-base conversion succeeds, because the Child object includes a complete Base object.
class MyBase
{
public:
virtual void test() {}
};
class MyChild : public MyBase {};
int main()
{
MyChild *child = new MyChild();
MyBase *base = dynamic_cast<MyBase*>(child); // ok
}
The next example attempts to convert a MyBase pointer to a MyChild pointer. Since the Base object does not contain a complete Child object this pointer conversion will fail. To indicate this, the dynamic cast returns a null pointer. This gives a convenient way to check whether or not a conversion has succeeded during run-time.
MyBase *base = new MyBase();
MyChild *child = dynamic_cast<MyChild*>(base);
if (child == 0)
std::cout << "Null pointer returned";
If a reference is converted instead of a pointer, the dynamic cast will then fail by throwing a bad_cast exception. This needs to be handled using a try-catch statement.
#include <exception>
// …
try
{
MyChild &child = dynamic_cast<MyChild&>(*base);
}
catch(std::bad_cast &e)
{
std::cout << e.what(); // bad dynamic_cast
}
Dynamic or static cast
The advantage of using a dynamic cast is that it allows the programmer to check whether or not a conversion has succeeded during run-time. The disadvantage is that there is a performance overhead associated with doing this check. For this reason using a static cast would have been preferable in the first example, because a derived-to-base conversion will never fail.
MyBase *base = static_cast<MyBase*>(child); // ok
However, in the second example the conversion may either succeed or fail. It will fail if the MyBase object contains a MyBase instance and it will succeed if it contains a MyChild instance. In some situations this may not be known until run-time. When this is the case dynamic cast is a better choice than static cast.
// Succeeds for a MyChild object
MyChild *child = dynamic_cast<MyChild*>(base);
If the base-to-derived conversion had been performed using a static cast instead of a dynamic cast the conversion would not have failed. It would have returned a pointer that referred to an incomplete object. Dereferencing such a pointer can lead to run-time errors.
// Allowed, but invalid
MyChild *child = static_cast<MyChild*>(base);
// Incomplete MyChild object dereferenced
(*child);
Const cast
This one is primarily used to add or remove the const modifier of a variable.
const int myConst = 5;
int *nonConst = const_cast<int*>(&myConst); // removes const
Although const cast allows the value of a constant to be changed, doing so is still invalid code that may cause a run-time error. This could occur for example if the constant was located in a section of read-only memory.
*nonConst = 10; // potential run-time error
const cast is instead used mainly when there is a function that takes a non-constant pointer argument, even though it does not modify the pointee.
void print(int *p)
{
std::cout << *p;
}
The function can then be passed a constant variable by using a const cast.
print(&myConst); // error: cannot convert
// const int* to int*
print(nonConst); // allowed
Source and More Explanations
You should look at the article C++ Programming/Type Casting.
It contains a good description of all of the different cast types. The following taken from the above link:
const_cast
const_cast(expression) The const_cast<>() is used to add/remove
const(ness) (or volatile-ness) of a variable.
static_cast
static_cast(expression) The static_cast<>() is used to cast between
the integer types. 'e.g.' char->long, int->short etc.
Static cast is also used to cast pointers to related types, for
example casting void* to the appropriate type.
dynamic_cast
Dynamic cast is used to convert pointers and references at run-time,
generally for the purpose of casting a pointer or reference up or down
an inheritance chain (inheritance hierarchy).
dynamic_cast(expression)
The target type must be a pointer or reference type, and the
expression must evaluate to a pointer or reference. Dynamic cast works
only when the type of object to which the expression refers is
compatible with the target type and the base class has at least one
virtual member function. If not, and the type of expression being cast
is a pointer, NULL is returned, if a dynamic cast on a reference
fails, a bad_cast exception is thrown. When it doesn't fail, dynamic
cast returns a pointer or reference of the target type to the object
to which expression referred.
reinterpret_cast
Reinterpret cast simply casts one type bitwise to another. Any pointer
or integral type can be casted to any other with reinterpret cast,
easily allowing for misuse. For instance, with reinterpret cast one
might, unsafely, cast an integer pointer to a string pointer.
FYI, I believe Bjarne Stroustrup is quoted as saying that C-style casts are to be avoided and that you should use static_cast or dynamic_cast if at all possible.
Barne Stroustrup's C++ style FAQ
Take that advice for what you will. I'm far from being a C++ guru.
Avoid using C-Style casts.
C-style casts are a mix of const and reinterpret cast, and it's difficult to find-and-replace in your code. A C++ application programmer should avoid C-style cast.
C-style casts conflate const_cast, static_cast, and reinterpret_cast.
I wish C++ didn't have C-style casts. C++ casts stand out properly (as they should; casts are normally indicative of doing something bad) and properly distinguish between the different kinds of conversion that casts perform. They also permit similar-looking functions to be written, e.g. boost::lexical_cast, which is quite nice from a consistency perspective.
dynamic_cast has runtime type checking and only works with references and pointers, whereas static_cast does not offer runtime type checking. For complete information, see the MSDN article static_cast Operator.
dynamic_cast only supports pointer and reference types. It returns NULL if the cast is impossible if the type is a pointer or throws an exception if the type is a reference type. Hence, dynamic_cast can be used to check if an object is of a given type, static_cast cannot (you will simply end up with an invalid value).
C-style (and other) casts have been covered in the other answers.