dynamic_cast
У мові програмування C оператор dynamic_cast
є частиною механізму динамічної ідентифікації типів даних, який дозволяє виконувати приведення типів даних. На відміну від звичайного приведення типів у стилі С, перевірка коректності приведення типів відбувається під час виконання програми. Оператор dynamic_cast
можна застосовувати до вказівників або посилань. Якщо відбувається приведення вказівника до типу, яким об’єкт фактично не є, то результатом приведення буде нульовий вказівник. При роботі з посиланнями, якщо приведення неможливе, буде згенеровано виняток (exception) std::bad_cast. Такою поведінкою оператор dynamic_cast
подібний до приведення типів у таких мовах програмування, як Java, і відрізняється від приведення в мові С, де коректність приведення типу під час виконання програми не перевіряється.
Припустимо, у нас є функція, що приймає аргументом об’єкт типу A
і повинна виконати деякі додаткові дії у випадку, якщо параметр насправді є об’єктом типу B
— нащадком класу A
. Таку поведінку можна реалізувати, використавши dynamic_cast
у наступний спосіб.
#include <typeinfo> // Для std::bad_cast
#include <iostream> // Для std::cerr та ін.
class A
{
public:
// Механізм динамічного визначення типів даних можливий тільки для поліморфних
// класів (тобто класів, що містять хоча б одну віртуальну функцію)
virtual void foo();
// інші члени класу...
};
class B : public A
{
public:
void methodSpecificToB();
// інші члени класу...
};
void my_function(A& my_a)
{
try
{
B& my_b = dynamic_cast<B&>(my_a);
my_b.methodSpecificToB();
}
catch (const std::bad_cast& e)
{
std::cerr << e.what() << std::endl;
std::cerr << "Цей об\'єкт не є об\'єктом класу B" << std::endl;
}
}
Можна записати аналогічний код з використанням указівників замість посилань:
void my_function(A* my_a)
{
B* my_b = dynamic_cast<B*>(my_a);
if (my_b)
my_b->methodSpecificToB();
else
std::cerr << "Цей об\'єкт не є об\'єктом класу B" << std::endl;
}