fork download
  1. #include <iostream>
  2. #include <typeinfo>
  3.  
  4. struct Shape { virtual ~Shape() {}; };
  5. struct Circle : Shape {};
  6. struct Square : Shape {};
  7. struct Other {};
  8.  
  9. int main() {
  10. Circle c;
  11. Shape & s = c; // Upcast: normal and OK
  12. // More explicit but unnecessary:
  13. s = static_cast<Shape&>(c);
  14. std::cout << "Address of `s` = " << &s << std::endl;
  15.  
  16. // (Since upcasting is such a safe and common
  17. // operation, the cast becomes cluttering)
  18.  
  19. // Static Navigation of class hierarchies
  20. // requires extra type information:
  21. // C++ RTTI
  22. if (typeid(s) == typeid(Circle))
  23. {
  24. Circle & cp = static_cast<Circle&>(s);
  25. std::cout << "It's a circle!" << std::endl;
  26. std::cout << "Address = " << &cp << std::endl;
  27. }
  28. if (typeid(s) == typeid(Square))
  29. {
  30. Square & sp = static_cast<Square&>(s);
  31. std::cout << "It's a square!" << std::endl;
  32. std::cout << "Address = " << &sp << std::endl;
  33. }
  34. // Static navigation is ONLY an efficiency hack;
  35. // dynamic_cast is always safer. However:
  36. // Other & op = static_cast<Other&>(s);
  37. // Conveniently gives an error message, while
  38. // that would be undefined behavior (UB)!
  39. // Other& op2 = (Other&)s;
  40. // does not
  41. // AND *nothing* is guaranteed if we uncomment the UB
  42. // INCLUDING *anything* about the lines *before* the UB (yes, really!)
  43. }
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
Address of `s` = 0xbfa675ec
It's a circle!
Address = 0xbfa675ec