dynamic_cast
помогает проверить достоверность при выполнении downcasting.
Возвращает значение NULL или выдает исключение (std::bad_cast
для ссылок), если указатель или ссылка не могут быть безопасно понижены.
Вы бы использовали динамическое приведение вчасто используемый метод?У него большие накладные расходы? dynamic_cast
использует некоторые дополнительные RTTI(Run Time Type Information)
для определения достоверности приведения.Так что накладные расходы наверняка.Как правило, указатель на typeinfo
из type
будет добавлен к virtual table
.Обычно я говорю, потому что сам виртуальный механизм зависит от реализации компилятора (может отличаться для разных компиляторов).
Вам придется профилировать свой код с помощью некоторых хороших инструментов профилирования, чтобы определить, многократно ли вызов dynamic_cast
снижает производительность вашего кода.
Что именно является указателемвозвращается dynamic_cast
.Указатель на тот же адрес?указатель на другой экземпляр?
Это легче понять, когда вместо анализа downcasting с dynamic_cast
мы анализируем upcasting .Для типа base
и другого типа derived
, который наследуется от base
, тип derived
будет содержать подобъект типа base
.Когда указатель на объект derived
преобразуется в указатель на base
, результатом операции будет адрес субобъекта base
внутри derived
.Выполнение dynamic_cast
отменяет эту операцию и возвращает указатель на объект derived
, который содержит подобъект base
в адресе, переданном в качестве аргумента (static_cast
делает то же самое, но применяет возможное смещение без фактической проверки типа среды выполнения).
В простейшем случае при одиночном (не виртуальном) наследовании подобъект derived
будет выровнен base
, но в случае множественного наследования,это не будет иметь место:
struct base {
int x;
virtual void foo() {}
};
struct another_base {
virtual void bar() {}
};
struct derived : base, another_base {};
int main() {
derived d;
base * b = &d; // points to the base subobject inside derived
another_base * o = &d; // points to the another_base subobject inside derived
std::cout << std::boolalpha
<< ( static_cast<void*>(b) == dynamic_cast<derived*>(b) ) << "\n"
<< ( static_cast<void*>(o) == dynamic_cast<derived*>(o) ) << std::endl;
}
Программа напечатает true
, false
.Обратите внимание, что вам нужно явно привести один из указателей к void*
, если вы хотите сравнить их, иначе компилятор выполнит неявное повышение значения указателя downcasted .