C++ Type Casting
C Type Casting
(type_name) expression
1 |
|
C++ Type Casting
Converting a value of a given type into another type is known as type-casting.
Conversion can be implicit or explicit.
C++ Implicit Conversion
Implicit conversions do not require any operator.
They are automatically performed when a value is copied to a compatible type.
1 |
|
C++ keyword explicit
The explicit specifier specifies that a constructor or conversion function (since C++11) doesn’t allow implicit conversions or copy-initialization. It may only appear within the decl-specifier-seq of the declaration of such a function within its class definition[^1].
C++ Explicit Conversion
Conversions that imply a different interpretation of the value, require an explicit conversion using type cast operator.
B b = (B) a;
B b = B (a);
Using type cast operators indiscriminately on classes and pointers to classes can lead to code that while being syntactically correct can cause runtime errors.
1 |
|
Four Specific Casting Operators
Traditional explicit type-casting allows to convert any pointer into any other pointer type, independently of the types they point to.
The subsequent call to member function will produce either a run-time error or unexpected result.
In order to control these types of conversions between classes, there are four specific casting operators:
static_cast, const_cast, dynamic_cast, reinterpret_cast.
static_cast
static_cast
can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. Such conversions are not always safe.
1 | class B {}; |
The static_cast
operator can also be used to perform any implicit conversion, including standard conversions and user-defined conversions. For example:
1 | typedef unsigned char BYTE; |
The static_cast
operator can explicitly convert an integral value to an enumeration type. If the value of the integral type does not fall within the range of enumeration values, the resulting enumeration value is undefined.
The static_cast
operator converts a null pointer value to the null pointer value of the destination type.
Any expression can be explicitly converted to type void by the static_cast
operator. The destination void type can optionally include the const
, volatile
, or __unaligned
attribute.
const_cast
const_cast
manipulates the constness of an object, either to be set or to be removed.
1 |
|
another example at MSDN:
1 |
|
you could use mutable
keyword on last example.
dynamic_cast
dynamic_cast
can be used only with pointers and references to objects.
Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class.
dynamic_cast
is always successful when we cast a class to one of its base classes.
1 | class B { }; |
This type of conversion is called an “upcast” because it moves a pointer up a class hierarchy, from a derived class to a class it is derived from. An upcast is an implicit conversion.
1 |
|
This type of conversion is called a “downcast” because it moves a pointer down a class hierarchy, from a given class to a class derived from it.
Another cross cast example:
1 |
|
Another more complicated example:
1 | class A {virtual void f();}; |
reinterpret_cast
reinterpret_cast
converts any pointer type to any other pointer type, even of unrelated classes.
1 | class A {}; |
Misuse of the reinterpret_cast
operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.
Questions
Is the function as below safe ? If not, what is the better way ?[^2]
1
2
3
4template <class T>
unsigned char* alias(T& x) {
return (unsigned char*)(&x);
}Which of the following lines will compile errors?[^3]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class A {
public:
virtual void foo() { }
};
class B {
public:
virtual void foo() { }
};
class C : public A , public B {
public:
virtual void foo() { }
};
void bar1(A *pa) {
B *pc = dynamic_cast<B*>(pa);
}
void bar2(A *pa) {
B *pc = static_cast<B*>(pa);
}
void bar3() {
C c;
A *pa = &c;
B *pb = static_cast<B*>(static_cast<C*>(pa));
}
int main() {
return 0;
}
External links
- When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
- C++ casting
- static_cast operator
- dynamic_cast operator
- reinterpret_cast operator
- TypeCasting
[^1]: explicit specifier
[^2]: How do you explain the differences among static_cast, reinterpret_cast, const_cast, and dynamic_cast to a new C++ programmer?
[^3]: http://blog.jobbole.com/108817/