Приведение dynamic_cast_cast

Синтаксис оператора:

dynamic_cast <имя типа>(<выражение>)

Оператор обеспечивает динамический контроль типов и способствует максимальной надежности преобразований.

Правила преобразований следующие. Если <имя типа> является указателем на прямой или непрямой базовый класс, соответствующий <выражению>, то результатом является ссылка типа <имя типа> (1). Это преобразование вверх. Если <имя типа> это void *, то результатом является ссылка на объект, соответствующий выражению в целом (2) и в дальнейшем можно использовать к полученному указателю оператор (тип), если это необходимо. Если тип <выражения> является базовым классом для типа <имя типа>, то делается run-time-проверка типа, чтобы удостовериться, что результатом вычисления выражения является ссылка на объект полность удовлетворяющий типу <имя типа>. И в этом случае результатом является действительно ссылка на объект (3). В остальных случаях указатель приобретает значение NULL и возникает исключительная ситуация bad_cast, которую можно «отловить» в программе и обработать.

Пример (Преобразование вверх)

class B{…};

class C: public B{…};

class D: public C{…};

void f(D *pd)

{

C *pc = dynamic_cast <C *>(pd); // все верно, т.к D подкласс класса C

B *pb = dynamic_cast <B *>(pd); // все верно, т.к B непрямой базовый класс для D

…………………………………………

}

Пример (void *)

class A{…}; class B{…};

……………………………………………..

A *pa = new A;

B *pb = new B;

void *pv = dynamic_cast <void *>(pa); // все верно, pv теперь ссылается на объект класса A

…………………………………………………………

pv = dynamic_cast <void *>(pb); // все верно, pv теперь ссылается на объект класса B

Пример (преобразование вниз)

class B{…};

class D: public B{…};

……………………………………………..

B *pb = new D; // допустимо, хотя редко применяется

B *pb2 = new B;

D *pd = dynamic_cast <D *>(pb); // все верно, т.к. pb ссылается на подходящий объект

………………………………………………

D *pd2 = dynamic_cast <D *>(pb2); // pd2=NULL, т.к. pb2 ссылается на объект, который

//делает ссылку pd2 опасной для вычислений

В случае использования dynamic_cast для преобразований «внутри» множественного наследования, возможно потребуются многоуровневые преобразования, чтобы избежать неоднозначностей.

Вопросы для самоконтроля

· В чем отличие динамического связывания от статического?

· Для чего применяются виртуальные методы?

· Как декларируются абстрактные классы?

· Можно ли создавать объекты абстрактных классов?

· Каким образом можно переопределить уровень доступа к методам или свойствам надклассов?

· Можно ли в качестве аргументов шаблонов указывать константы? – типы данных?

· Перечислите новые операторы приведения типов!

· Сформулируйте кратко назначение каждого из новых операторов приведения типов!

Вопросы для самостоятельного изучения

· Придумайте и запишите примеры применения новых операторов приведения типов данных!

Лекция 24. С++: стандартные блоки диалога, простые и структурные классы в вычислениях