Динамическая идентификация типа
Динамическая идентификация типа данных (англ. Run-time Type Information, Run-time Type Identification, RTTI ) — механизм, реализованный в языках программирования, который позволяет определить тип данных переменной или объекта во время выполнения программы.
Реализация
Существует множество реализаций такого механизма, но наиболее распространенные —
- ведение таблицы указателей на объекты
- хранение информации об объекте в памяти вместе с ним
Таким образом, операция определения типа сводится либо к поиску в таблице, либо к просмотру нескольких байт до адреса, на который указывает указатель на объект. У каждого способа есть свои преимущества и недостатки.
C++
В C++ для динамической идентификации типа данных применяются операторы dynamic_cast и typeid , для использования которых обычно необходимо включить RTTI (информация о типе во время выполнения) при компиляции модуля.
Оператор dynamic_cast пытается выполнить приведение к указанному типу с проверкой. Целевой тип операции должен быть типом указателя, ссылки или void* .
- Если целевой тип — тип указателя, то аргументом должен быть указатель на объект класса.
- Если целевой тип — ссылка, то аргумент должен также быть соответствующей ссылкой.
- Если целевым типом является void* , то аргумент также должен быть указателем, а результатом операции будет указатель, с помощью которого можно обратиться к любому элементу «самого производного» класса иерархии, который сам не может быть базовым ни для какого другого класса.
Оператор typeid возвращает ссылку на структуру type_info , которая содержит поля, позволяющие получить информацию о типе.
Delphi
Компилятор Borland Delphi сохраняет в исполняемом файле программы информацию о всех классах, используемых в ней — в виде структур определенного формата. При создании любого объекта в памяти перед ним (по отрицательным смещениям) располагается заголовок, в котором есть в том числе ссылка на структуру-описатель класса это объекта. Встроенные в язык функции работают с этой информацией прозрачно для программиста. Оператор is позволяет проверить является ли объект или тип наследником определённого типа, оператор as является аналогом dynamic_cast в C++
Заголовки объектов — также неявно — используются для автоматического управления памятью.
C#
В C# для определения типа объекта во время исполнения используется метод GetType , а также ключевые слова is и as , которые являются аналогами для typeid и dynamic_cast в C++ соответственно.
Wikimedia Foundation . 2010 .
Сведения о типах времени выполнения
Информация о типах времени выполнения (RTTI) — это механизм, позволяющий определить тип объекта во время выполнения программы. Функция RTTI была добавлена в язык C++, поскольку многие поставщики библиотек классов реализовывали ее самостоятельно. Это приводило к проблемам совместимости между библиотеками. Таким образом, стало очевидно, что необходима поддержка информации о типах времени выполнения на уровне языка.
Для ясности этот раздел о RTTI почти полностью посвящен указателям. Однако рассматриваемые понятия также применяются ко ссылкам.
Существует три основных элемента языка C++ для информации о типах времени выполнения.
- Оператор dynamic_cast . Используется для преобразования полиморфных типов.
- Оператор typeid . Используется для указания точного типа объекта.
- Класс type_info . Используется для хранения сведений о типе, возвращаемых оператором typeid .
См. также
Дополнительные ресурсы
Значок отказа согласно Закону Калифорнии о защите конфиденциальности потребителей (CCPA)
- Светлая
- Темная
- Высокая контрастность
- Предыдущие версии
- Блог
- Участие в доработке
- Конфиденциальность
- Условия использования
- Товарные знаки
- © Microsoft 2024
Дополнительные ресурсы
Значок отказа согласно Закону Калифорнии о защите конфиденциальности потребителей (CCPA)
- Светлая
- Темная
- Высокая контрастность
- Предыдущие версии
- Блог
- Участие в доработке
- Конфиденциальность
- Условия использования
- Товарные знаки
- © Microsoft 2024
Идентификация типа во время исполнения (RTTI)
Используя идентификацию типа времени исполнения (run-time type identification — RTTI) можно определить тип объекта во время исполнения программы. Для этого используется функция typeid. Для использования этой функции необходимо включить заголовочный файл typeinfo.h. Общая форма записи функции typeid имеет следующий вид:
Здесь объект является объектом, чей тип требуется определить. Функция typeid возвращает ссылку на объект типа typeinfo, который описывает тип объекта объект. (В проекте стандарта С++ этот тип называется type_info.) Класс typeinfo определяет следующие публичные члены:
bool operator== (const typeinfo &ob) const;
bool operator!= (const typeinfo &ob) const;
bool before(const typeinfo &ob) const;
const char *name() const;
Перегруженные операторы == и != обеспечивают сравнение типов. Функция before() возвращает истину, если вызываемый объект стоит выше в иерархии объектов, чем объект, используемый в качестве параметра. Функция before() предназначена большей частью для внутреннего использования. Возвращаемое ею значение не имеет ничего общего с иерархией классов или наследованием. Функция name() возвращает указатель на имя типа.
Когда функция typeid применяется к указателю на базовый класс полиморфного класса, она автоматически возвращает тип объекта, на который указывает указатель, в том числе любой класс, выведенный из базового класса. (Как уже говорилось, полиморфным классом называется класс, содержащий хотя бы одну виртуальную функцию.)
![]() |
ПАМЯТКА: Указатель обязательно должен быть разыменован. Следует также установить режим поддержки RTTI в опциях компилятора. |
Следующая программа демонстрирует использование функции typeid
Программа выдаст следующий результат на экран:
Typeid of i is int
p is pointing to an object of type BaseClass
p is pointing to an object of type Derived1
p is pointing to an object of type Derived2
Как уже отмечалось, применение функции typeid к указателю на базовый класс полиморфного типа позволяет определить фактический тип объекта, на который указывает указатель во время исполнения программы. Поэкспериментируем теперь, закомментировав виртуальную функцию f() в базовом классе, и посмотрим на результат.
RTTI не является тем средством, которое используется всякой программой. Однако при работе с полиморфными типами она позволяет знать тип объекта в любой ситуации.
C++, как работает RTTI
Я бы хотел понять, как в C++ работает RTTI . Мне понятно, как вызываются виртуальные методы. Это происходит через таблицу виртуальных методов, указатель на эту таблицу размещается в объекте каждого класса, который содержит виртуальные методы. У каждого класса с виртуальными методами есть своя таблица виртуальных методов. Но мне не совсем понятно, как во время исполнения определяется тип объекта. В объектах размещается какая-то дополнительная информация? Например, ID типа. И как следствие, я не понимаю, велико ли отличие между ручным приведением типов при помощи dynamic_cast и использованием паттерна visitor для реализации двойной диспетчеризации.
Отслеживать
задан 10 авг 2019 в 1:32
4,128 1 1 золотой знак 9 9 серебряных знаков 23 23 бронзовых знака
В разных компиляторах может быть сделано по-разному. Вот, к примеру, небольшая заметка по RTTI в какой-то из версий студии.
10 авг 2019 в 6:14
«использованием паттерна visitor для реализации двойной диспетчеризации» Можно пример, как это выглядит?
