Show Lecture.Casting as a slide show.
(
type)
value
(
value)
const_cast<
type>(
value)
static_cast<
type>(
value)
dynamic_cast<
type>(
value)
reinterpret_cast<
type>(
value)
In C, casting worked like this:
float f = 3.14; unsigned int *p = &f; printf("%08x", *p);
c.c: In function 'main': c.c:2: warning: initialization of 'unsigned int *' from incompatible pointer type 'float *' 4048f5c3
float f = 3.14; unsigned int *p = (unsigned int *) &f; printf("%08x", *p);
4048f5c3
This works in C++, but don’t. Detect with g++ -Wold-style-cast
.
This isn’t really casting, but sure is similar:
int n; n = int(3.14); cout << "n is " << n << '\n';
n is 3
Of course, an actual programmer would just do this, even though a fussy compiler might issue a warning:
int n = 3.14; cout << "n is " << n << '\n';
n is 3
The problem with C-style casting is that it’s too powerful. It’s an “anything goes” sort of operation:
long l = (long) "Krypto the Superdog"; cout << l << '\n';
4196616
That’s the address of the string (array of char
) as a decimal number,
a thing of questionable value. Hope it fits into a long
!
In C++, it was decided to break up the vast power of the C-style cast into separate tools:
const_cast<
type>(
value)
: remove const
ness
static_cast<
type>(
value)
: usual conversions
dynamic_cast<
type>(
value)
: object type conversion
reinterpret_cast<
type>(
value)
: go nuts
const_cast
char *p = "☹"; cout << p;
c.cc:1: warning: ISO C++ forbids converting a string constant to 'char*' ☹
That failed, because p
is type char *
,
whereas "☹"
is type const char[]
or const char *
.
const_cast
const_cast<
type>(
value)
removes const
ness.
You have to specify the new type, but it must be the original
type with const
added.
char *p = const_cast<char *>("☺"); cout << p;
☺
const_cast
However, const_cast
can only change const
ness, not type:
const double *p = const_cast<const double *>("☹"); cout << p;
c.cc:1: error: invalid const_cast from type 'const char*' to type 'const double*'
This way, if you see const_cast
, you know that it’s
only removing const
ness.
static_cast
static_cast<
type>(
value)
: usual conversions
double d = 3.15; int i = static_cast<int>(d); cout << i;
3
int i = static_cast<int>("123"); cout << i;
c.cc:1: error: invalid static_cast from type 'const char [4]' to type 'int'
dynamic_cast
dynamic_cast<
type>(
value)
: object type conversion
class Base { public: virtual void foo() { } }; class Derived : public Base { }; Base b, *bp = &b; Derived *dp = dynamic_cast<Derived *>(bp); if (dp == nullptr) cout << "Conversion failed.\n"; else cout << "Conversion succeeded.\n";
Conversion failed.
reinterpret_cast
reinterpret_cast<
type>(
value)
: go nuts
double avo = 6.022e23; long l = reinterpret_cast<long>(&avo); cout << l << endl; int n = *reinterpret_cast<int *>(&avo); cout << n << endl; int *p = reinterpret_cast<int *>(42); cout << "Goodbye, cruel world: " << *p << endl;
140721191733888 -195565037 SIGSEGV: Segmentation fault
string
containing digits
to an int
.
string s = "3.1415926535"; double d = stod(s); cout << "π ≅ " << d << '\n'; s = "42"; int i = stoi(s, nullptr, 16); cout << s << " base 16 = " << i << " base 10\n";
π ≅ 3.14159 42 base 16 = 66 base 10