Во-первых, CBase
должен быть полиморфным, чтобы вы могли использовать dynamic_cast
здесь (то есть он должен иметь хотя бы одну virtual
функцию-член). В противном случае вы не можете использовать dynamic_cast
.
Тем не менее приведение от &b
к CDerived*
равно , а не неправильно: pd
будет нулевым указателем.
dynamic_cast
обладает полезным свойством, что при сбое приведения (то есть, если объект, на который указывает указатель, не относится к целевому типу), он возвращает нулевой указатель. Это позволяет вам проверить фактический тип объекта. Например:
CBase b;
CDerived d;
CBase* pb = &b;
CBase* pd = &d;
CDerived* xb = dynamic_cast<CDerived*>(pb); // xb is null!
CDerived* xd = dynamic_cast<CDerived*>(pd); // xd points to d!
Ваш код был бы неверным, если бы вы использовали static_cast
, поскольку он преобразуется без выполнения какой-либо проверки типа во время выполнения, что означает, что нет способа проверить, успешно ли приведено приведение. Если вам когда-либо нужно привести иерархию классов, и вы точно не знаете, принадлежит ли объект к производному типу, к которому вы пытаетесь привести тип, вы должны использовать dynamic_cast
.