#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();
Base& upcast = static_cast<Base&>(concrete_derived);
Derived* downcast_concrete = dynamic_cast<Derived*>(&concrete_base);
Derived* downcast = dynamic_cast<Derived*>(derived_through_base_interface);
assert(downcast_concrete == nullptr);
assert(downcast != nullptr);
Base sliced = static_cast<Base>(concrete_derived);
concrete_base.foo();
concrete_derived.foo();
concrete_derived.bar();
derived_through_base_interface->foo();