Scott Meyer
в своей книге Effective C++
говорит, что dynamic_cast
используется для безопасного приведения типов вниз или поперек иерархии наследования. То есть вы используете dynamic_cast для приведения указателей или ссылок на объекты базового класса к указателям или ссылкам на производные или одноуровневые объекты базового класса таким образом, чтобы вы могли определить, были ли приведения успешными.
Неудачные приведения обозначаются нулевым указателем (при приведении указателей) или исключением (при приведении ссылок).
Я хотел бы получить два фрагмента кода, показывающих неудачное приведение в случае указателя приведения, и может быть указана ссылка на приведение.
Вы просите примеры кода, проверяющего, является ли указатель нулевым, и кода, перехватывающего исключение? — person nitin_cherian schedule 16.07.2012
Нет. Я не понимаю, как броски могут потерпеть неудачу, как упоминал Скотт. Фрагмент кода определенно поможет. — person nitin_cherian schedule 16.07.2012
en.wikipedia.org/wiki/Dynamic_cast — person nitin_cherian schedule 16.07.2012
@JamesMcNellis: Пожалуйста, помните, что все мы начинаем как новички. В любом случае, я получил фрагмент кода от Рида. — person nitin_cherian schedule 16.07.2012
Для указателей это простая проверка на нулевое значение:
Для справки можно поймать:
@LinuxPenseur Проверка предполагает, что a имеет допустимое значение. Вы должны сначала проверить это (для распределения). Проверка dynamic_cast проверяет, можно ли безопасно преобразовать A в B, поэтому проверка против
b
дляNULL
, то есть: b равно null, а a не равно null. — person nitin_cherian; 16.07.2012@ReedCopsey: Что означает мой
safe cast
. В какой ситуации b может стать NULL? — person nitin_cherian; 16.07.2012dynamic_cast
используется, когда класс является полиморфным (имеет функциюvirtual
) и выполняет проверки во время выполнения, возвращая указательNULL
. Используяdynamic_cast
, вы говорите ему делать именно то, что вы хотите, вместо преобразований C-Style, когда он пробует различные типы преобразований.dynamic_cast
также используется, когда вы не знаете, какой объект нужно преобразовать, вместоstatic_cast
, который используется для неполиморфных классов и когда известны оба типа преобразования. — person nitin_cherian; 16.07.2012@ViniciusHorta: я не хотел видеть определение из учебника, которое совсем не то, что я просил — person nitin_cherian; 16.07.2012
@LinuxPenseur:
new()
не обязательно возвращает нулевой указатель в случае сбоя, вам также может потребоваться проверить исключение здесь.b
станетNULL
, еслиa
не является экземпляромB
. — person nitin_cherian; 16.07.2012@g-makulik: обычная версия
new
никогда не вернет нулевой указатель — она либо вернет действительный указатель, либо выдаст исключение. Чтобы получить нулевой указатель при ошибке, вы используетеnew(nothrow) whatever;
— person nitin_cherian; 16.07.2012Прошу прощения за вопрос новичка, но эквивалентно ли
if (b)
if (b == NULL)
? — person nitin_cherian; 22.03.2016@Suzi это будет то же самое, что и != NULL — person nitin_cherian; 22.03.2016
Основываясь на комментарии ОП («Я не понимаю, как приведения могут завершиться неудачно, как упоминал Скотт»), реальный вопрос здесь действительно что-то вроде: «Как может
dynamic_cast
потерпеть неудачу?»Это может привести к сбою, когда целевой тип не соответствует динамическому типу объекта. Для простого примера:
Хотя здесь
a
может указывать на объект типаB
, на самом деле указывает на объект типаA
. Когда мы пытаемся выполнить dynamic_cast, чтобы он указывал наB
, это не удается. Во второй попытке у нас снова есть указатель, который не только но действительно указывает на объект типаB
. Поскольку это так, в этом случае динамическое приведение кB *
завершается успешно.Основная ситуация не меняется (сильно) для эталонного случая, просто
a
,b
иc
становятся ссылками вместо указателей, и мы отмечаем сбой, перехватывая исключение (которое @ReedCopsey уже продемонстрировано достаточно хорошо, чтобы я не думаю есть что добавить нового)Вот полный пример, который показывает, как
dynamic_cast
может не создать указатель.В реальном мире вы будете пытаться создавать указатели, которые не были созданы так просто, возможно, они происходят, например, от
vector
.