Динамическая идентификация типов операций
Динамическая идентификация типа данных (run-time type identification, RTTI) – механизм в некоторых языках программирования, который позволяет определить тип данных переменной или объекта во время выполнения программы. Существует множество реализаций такого механизма, но наиболее распространёнными являются:
таблица указателей на объекты;
хранение информации об объекте в памяти вместе с ним.
Таким образом, операция определения типа сводится либо к поиску в таблице, либо к просмотру нескольких байт до адреса, на который указывает указатель на объект. У каждого способа есть свои преимущества и недостатки. К примеру, в первом случае для определения типа переменной требуется производить операции поиска по таблице указателей. А во втором случае, переменные начинают занимать больше места в оперативной памяти, чем ожидается, ведь к их известному размеру добавляется некоторое количество байтов, нужных для идентификации их типа.
В настоящей работе для операций используется второй подход. Для создания операций конкретного типа используются классы-адаптеры, каждый из которых представляет определенную операцию и имеет, помимо прочего, статический метод, возвращающий идентификатор типа операции.
struct ConcreteOp : public BaseOp {
// ...
static Operation::SpecId getSpecId() {
static char specId = 0;
return &specId;
}
static bool implementsSpecById(Operation::SpecId specId) {
return specId == getSpecId() || BaseOp::implementsSpecById(specId);
}
};
Таким образом, при создании конкретной операции в нее также записывается значение идентификатора типа операции из связанного адаптера. Это позволяет реализовать для класса операции следующие методы, использующие RTTI:
struct Operation {
using SpecId = void *;
SpecId specId;
// ...
public:
template <typename AdaptorType> bool is() const;
template <typename AdaptorType> AdaptorType as();
template <typename AdaptorType> AdaptorType findParent() const;
// ...
};
Эти методы позволяют проверить, является ли операция конкретной операцией, привести ее к указанному типу, а также найти в дереве операций среди предков узла операцию, имеющую определенный тип. Реализованный механизм применяется во многих компонентах проекта, работающих с деревом операций, например, в семантическом анализаторе.