Casting¶
C Style Casting¶
#include <iostream>
#include <cmath>
int main(int argc, char *argv[]) {
double x = M_PI;
int xx = (int) x;
std::cout << xx << "\n";
long z = LONG_MAX;
int zz = (int) z; // dangerous. overflow
std::cout << zz << "\n";
}
Const Casting¶
#include <iostream>
void f(const int &x) {
const_cast<int &>(x) = 0;
}
int main(int argc, char *argv[]) {
int x = 123;
f(x);
std::cout << x << "\n";
}
Reinterpret Casting¶
#include <iostream>
#include <iomanip>
struct A { int x; int y; };
int main(int argc, char *argv[]) {
A a{1, 2};
// convert a struct to a byte array
char *buf = reinterpret_cast<char *>(&a);
for (int i = 0; i < sizeof(A); ++i) {
std::cout << static_cast<int>(buf[i]) << " ";
}
// output: 1 0 0 0 2 0 0 0
}
Static Casting¶
#include <iostream>
#include <memory>
struct A {
virtual void f() { std::cout << __func__ << "\n"; }
virtual ~A() = default;
};
struct B : public A {;
B(int *x) : x_{x} {}
int *g() { return x_; }
int *x_;
};
int main(int argc, char *argv[]) {
auto a = std::make_unique<A>();
// downcasting may be dangerous
auto b = static_cast<B *>(a.get());
auto x = b->g();
std::cout << *x << "\n";
}
Dynamic Casting¶
#include <iostream>
#include <memory>
struct A {
virtual void f() { std::cout << __func__ << "\n"; }
};
struct B : public A {
void f() override { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
int main(int argc, char *argv[]) {
auto a = std::make_unique<A>();
auto b = std::make_unique<B>();
// downcast
auto bb = dynamic_cast<B *>(a.get());
std::cout << "Is dynamic_cast(*a) to *b success? " << !!bb << "\n";
// output: Is dynamic_cast(*a) to *b success? 0
// upcast
auto aa = dynamic_cast<A *>(b.get());
std::cout << "Is dynamic_cast(*b) to *a success? " << !!aa << "\n";
// output: Is dynamic_cast(*a) to *b success? 1
}