Приведение к derived_1
завершится неудачей, поскольку derived_2
является объектом base
, но не a derived_1
.Следовательно, вы не можете выполнить «боковое приведение» к нужному типу указателя.
Не то, что при сбое dynamic_cast
возвращается nullptr
( за исключением ссылочных типов ).Это в конечном итоге приводит к ошибке сегментации в вашем коде (в общем, я бы посоветовал вам всегда добавлять if (d_1 != nullptr)
перед использованием динамически приводимого объекта).
Обновление:
Кстати, это действительно хороший пример необходимости dynamic_cast
.Даже если у вас может возникнуть соблазн использовать static_cast
в вашем примере, и он скомпилируется, вы будете иметь дело с неопределенным поведением .Использование static_cast
будет компилироваться без всплесков, но на самом деле вы будете работать с неработающим типом.Предположим, derived_1::printing()
обращается к некоторой переменной derived_1::a
, которой нет в derived_2
.При статическом приведении объекта derived_2
(у которого нет a
) к derived_1
объекту d_1
, вы могли бы ошибочно предположить, что d_1
содержит некоторый действительный a
, что не так..
Пример:
// ...
struct derived_1 :public base
{
const int a = 123;
void printing() override {cout<<"derived_1 printing " << endl;}
void foo() { cout << "Foo using constant = " << a << endl; }
};
// ...
int main()
{
base * b = new derived_2();
derived_1 *d_1 = static_cast<derived_1*>(b);
d_1->printing(); // Will call derived_2::printing(), which is not what you expect!
d_1->foo(); // Won't show a = 123 but some nonesense (mostly 0),
// because a is not defined in derived_2.
}