Независимо от компилятора, вы всегда можете сэкономить на времени выполнения, если можете себе это позволить
if (typeid(a) == typeid(b)) {
B* ba = static_cast<B*>(&a);
etc;
}
вместо того
B* ba = dynamic_cast<B*>(&a);
if (ba) {
etc;
}
Первое включает в себя только одно сравнение std::type_info
; последнее обязательно включает обход дерева наследования и сравнение.
В прошлом ... как все говорят, использование ресурсов зависит от конкретной реализации.
Я согласен со всеми остальными комментариями, что автор должен избегать RTTI по причинам дизайна. Тем не менее, есть есть веские причины использовать RTTI ( в основном из - за повышения :: любой). Имея это в виду, полезно знать фактическое использование ресурсов в распространенных реализациях.
Недавно я провел кучу исследований RTTI в GCC.
tl; dr: RTTI в GCC использует незначительное место и typeid(a) == typeid(b)
очень быстро работает на многих платформах (Linux, BSD и, возможно, встроенные платформы, но не mingw32). Если вы знаете, что вы всегда будете на благословенной платформе, RTTI очень близка к бесплатной.
Песчаные детали:
GCC предпочитает использовать определенный «независимый от производителя» C ++ ABI [1] и всегда использует этот ABI для целей Linux и BSD [2]. Для платформ, которые поддерживают этот ABI, а также слабую связь, typeid()
возвращает непротиворечивый и уникальный объект для каждого типа, даже через границы динамической связи. Вы можете проверить &typeid(a) == &typeid(b)
или просто положиться на тот факт, что портативный тест на typeid(a) == typeid(b)
самом деле просто сравнивает указатель внутри.
В предпочтительном ABI GCC класс vtable всегда содержит указатель на структуру RTTI для каждого типа, хотя он может не использоваться. Таким образом, typeid()
сам вызов должен стоить столько же, сколько любой другой поиск в vtable (так же, как вызов виртуальной функции-члена), а поддержка RTTI не должна использовать дополнительное пространство для каждого объекта.
Из того, что я могу разглядеть, структуры RTTI, используемые GCC (это все подклассы std::type_info
), содержат только несколько байтов для каждого типа, кроме имени. Мне не ясно, присутствуют ли имена в выходном коде даже с -fno-rtti
. В любом случае, изменение размера скомпилированного двоичного файла должно отражать изменение в использовании памяти во время выполнения.
Быстрый эксперимент (с использованием GCC 4.4.3 в 64-битной Ubuntu 10.04) показывает, что -fno-rtti
фактически увеличивает размер двоичного файла простой тестовой программы на несколько сотен байт. Это происходит последовательно между комбинациями -g
и -O3
. Я не уверен, почему размер увеличится; одна возможность состоит в том, что код STL GCC ведет себя иначе без RTTI (так как исключения не будут работать).
[1] Известный как Itanium C ++ ABI, документированный по адресу http://www.codesourcery.com/public/cxx-abi/abi.html . Имена ужасно сбивают с толку: имя относится к оригинальной архитектуре разработки, хотя спецификация ABI работает на многих архитектурах, включая i686 / x86_64. Комментарии во внутреннем источнике GCC и коде STL ссылаются на Itanium как «новый» ABI в отличие от «старого», который они использовали ранее. Хуже того, «новый» / Itanium ABI относится ко всем версиям, доступным через -fabi-version
; «старый» ABI предшествовал этой версии. GCC принял Itanium / versioned / "новый" ABI в версии 3.0; «старый» ABI использовался в 2.95 и ранее, если я правильно читаю их журналы изменений.
[2] Я не смог найти ни одного ресурса, перечисляющего std::type_info
стабильность объекта в зависимости от платформы. Для компиляторов , я имел доступ к, я использовал следующее: echo "#include <typeinfo>" | gcc -E -dM -x c++ -c - | grep GXX_MERGED_TYPEINFO_NAMES
. Этот макрос управляет поведением operator==
for std::type_info
в STL GCC, начиная с GCC 3.0. Я обнаружил, что mingw32-gcc подчиняется ABI Windows C ++, где std::type_info
объекты не являются уникальными для типа в разных DLL; typeid(a) == typeid(b)
звонки strcmp
под одеялом. Я предполагаю, что в однопрограммных встраиваемых целях, таких как AVR, где нет кода для ссылки, std::type_info
объекты всегда стабильны.