Dynamic cast
В языке программирования 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), а программа не готова к этому.
См. также
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.