В языке программирования C++ операция dynamic_cast преобразует тип данных (указатель или ссылку) вниз по иерархии наследования (из типа-предка в тип-потомок), с проверкой с помощью динамической идентификации типа данных, корректно ли приведение. Этот тип преобразования называется "нисходящим приведением типа", поскольку при нем указатель перемещается вниз по иерархии классов: от базового класса к производному классу.
В отличие от обычного приведения типа в стиле Си, проверка корректности приведения типов производится во время выполнения программы. Оператор dynamic_cast может быть применён к указателям или ссылкам. Основное назначение dynamic_cast - преобразование указателя, который содержит адрес объекта-родителя, к указателю типа объекта-потомка. При невозможности преобразования (типы не состоят в родстве) будет получен нулевой указатель. При работе со ссылками при невозможности преобразования типа будет сгенерировано исключение 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;
Аналогичный код для функции my_function может быть записан с использованием указателей вместо ссылок: 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; } Возможные логические ошибки Ошибки возможны, если преобразование не состоялось (операция вернула nullptr или выбросила исключение bad_cast), а программа не готова к этому.
См. также
Приведение типа Динамическая идентификация типа данных () static_cast
Категория:Синтаксис C++ Категория:Статьи с примерами кода C++ Категория:Типы данных