Введение
Особенность языка программирования, предоставляющая информацию о типе данных объекта во время выполнения. В компьютерном программировании информация о типе во время выполнения (или идентификация типа во время выполнения, RTTI) — это функция некоторых языков программирования (таких как C++, Object Pascal и Ada), которая предоставляет информацию о типе данных объекта во время выполнения. Информация о типе во время выполнения может быть доступна для всех типов или только для типов, которые явно её поддерживают (как в случае с Ada). Информация о типе во время выполнения является специализацией более общей концепции, называемой интроспекцией типов. В первоначальной разработке C++ Бьярне Строструп не включал информацию о типе во время выполнения, поскольку считал, что этот механизм часто используется не по назначению.
In computer programming, run time type information or run time type identification (RTTI) is a feature of some programming languages (such as C++, Object Pascal, and Ada) that exposes information about an object's data type at runtime. Run time type information may be available for all types or only to types that explicitly have it (as is the case with Ada). Run time type information is a specialization of a more general concept called type introspection. In the original C++ design, Bjarne Stroustrup did not include run time type information, because he thought this mechanism was often misused.
Обзор
В C++ RTTI может использоваться для выполнения безопасных приведений типов с помощью оператора `dynamic_cast<>` и для манипулирования информацией о типах во время выполнения с использованием оператора `typeid` и класса `std::type_info`. В Object Pascal RTTI может использоваться для выполнения безопасных приведений типов с помощью оператора `as`, проверки принадлежности объекта к классу с помощью оператора `is` и манипулирования информацией о типах во время выполнения с помощью классов, содержащихся в модуле RTTI (т.е. классов: `TRttiContext`, `TRttiInstanceType` и т.д.). В Ada объекты помеченных типов также хранят тег типа, что позволяет идентифицировать тип этих объектов во время выполнения. Оператор `in` может использоваться для проверки во время выполнения, является ли объект определенным типом и может ли он быть безопасно преобразован к нему. RTTI доступен только для полиморфных классов, то есть классов, имеющих хотя бы один виртуальный метод. На практике это не является ограничением, поскольку базовые классы должны иметь виртуальный деструктор, чтобы объекты производных классов могли корректно освобождать ресурсы при удалении через указатель на базовый класс. Некоторые компиляторы предоставляют флаги для отключения RTTI. Использование этих флагов может уменьшить общий размер приложения, что особенно полезно при разработке для систем с ограниченным объемом памяти.
C++ typeid
Зарезервированное слово `typeid` (ключевое слово) используется для определения класса объекта во время выполнения. Оно возвращает ссылку на объект `std::type_info`, который существует до конца программы. Использование `typeid` в неполиморфном контексте часто предпочтительнее, чем динамический приведение типов `dynamic_cast<class type>`, в ситуациях, когда требуется только информация о классе, поскольку `typeid` всегда выполняется за постоянное время, а `dynamic_cast` может потребовать обхода иерархии наследования класса его аргумента во время выполнения. Некоторые аспекты возвращаемого объекта определены реализацией, например, `std::type_info::name`, и не могут быть гарантированно одинаковыми при использовании разных компиляторов. Объекты класса `std::bad_typeid` генерируются, когда выражение для `typeid` является результатом применения унарного оператора `*` к нулевому указателю. Выбрасывается ли исключение для других нулевых ссылок, зависит от реализации. Иными словами, для гарантированного возникновения исключения выражение должно иметь вид `typeid(*p)`, где `p` – любое выражение, результатом которого является нулевой указатель.
C++ dynamic_cast и Java cast
Динамический оператор `dynamic_cast` в C++ используется для приведения ссылки или указателя к более конкретному типу в иерархии классов. В отличие от `static_cast`, целью `dynamic_cast` должен быть указатель или ссылка на класс. В отличие от `static_cast` и приведения типов в стиле C (где проверка типа происходит во время компиляции), проверка безопасности типа выполняется во время выполнения. Если типы несовместимы, будет выброшено исключение (при работе со ссылками) или возвращен нулевой указатель (при работе с указателями). Приведение типов в Java ведет себя аналогично: если объект, к которому выполняется приведение, на самом деле не является экземпляром целевого типа и не может быть преобразован в него методом, определенным языком, будет выброшено исключение `java.lang.ClassCastException`.