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
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <cassert>
struct Base {
virtual void foo() { std::cout << "Base foo\n"; }
};
struct Derived : public Base {
void foo() override { std::cout << "Derived foo\n"; }
void bar() { std::cout << "Derived bar\n"; }
};
int main()
{
Base concrete_base;
Derived concrete_derived;
Base* derived_through_base_interface = new Derived();
// Upcast - derived pointer or reference to base
Base& upcast = static_cast<Base&>(concrete_derived);
// Downcast - base pointer or reference to derived
Derived* downcast_concrete = dynamic_cast<Derived*>(&concrete_base); // This appears to work, but will return nullptr, so make sure to check the pointer before using it!
Derived* downcast = dynamic_cast<Derived*>(derived_through_base_interface);
assert(downcast_concrete == nullptr);
assert(downcast != nullptr);
// Slice - derived *value* to base *value*
Base sliced = static_cast<Base>(concrete_derived);
concrete_base.foo(); // "Base foo"
// concrete_base.bar(); // error, Base does not have member named "bar"
concrete_derived.foo(); // "Derived foo"
concrete_derived.bar(); // "Derived bar"
derived_through_base_interface->foo(); // "Derived foo"
// derived_through_base_interface->bar(); // error, Base does not have member named "bar"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:23:75: warning: dynamic_cast of 'Base concrete_base' to 'struct Derived*' can never succeed
         Derived* downcast_concrete = dynamic_cast<Derived*>(&concrete_base); // This appears to work, but will return nullptr, so make sure to check the pointer before using it!
                                                                           ^
Base foo
Derived foo
Derived bar
Derived foo
Derived foo
Derived foo
Derived bar
Base foo