2014-10-04 17 views
2

Класс является полиморфным. Почему оба печатают один и тот же вывод?Разница между статическим и динамическим литьем

class A 
{ 
public: 
    virtual void P(){ cout << "A" << endl; } 

}; 
class B : public A 
{ 
public: 
    void P()override{ 
     cout << "B" << endl; 
    } 
    B(){ cout << "Created B" << endl; s = "Created by B"; } 
    string s; 
}; 

А главное: Вариант 1:

A* a = new B(); // Created B 
B* b = static_cast<B*>(a); 
b->P(); B 
cout<<b->s<<endl; // Created by B 

И вариант 2:

A* a = new B(); 
    B* b = dynamic_cast<B*>(a); 
    if (b){ 
     b->P(); 
     cout << b->s << endl; // Prints same 
    } 
+0

Что вы ожидали, и почему? – quantdev

+0

Почему вопрос? Вы ожидали, что они напечатают различную продукцию? Если да, то почему? – AnT

ответ

7

Оба ваших примеров будут делать то же самое, и это нормально. Попробуйте с этим вместо того, чтобы:

A* a = new A(); 

В этом случае static_cast будет «добиться успеха» (хотя это неопределенное поведение), в то время как dynamic_cast будет «глючить» (возвращая nullptr, который вы уже проверить на).

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

Если вы хотите знать , то какdynamic_cast делает это, читает о RTTI, информацию о времени выполнения. Это дополнительная информация, которую C++ делает в некоторых случаях для проверки типа объекта (это важно для этого, а также если вы используете typeid()).

+0

Thanks.John Zwinck –

+0

Почему важная виртуальная функция для использования dynamic_cast? –

+0

@Gui_C: Я не понимаю, что вы сейчас спрашиваете. –

1

В этом случае static_cast семантически эквивалентен dynamic_cast.

static_cast < new_type> (выражение)

2) Если new_type представляет собой указатель или ссылка на какой-то класс D и типа выражения является указателем или ссылки на его не виртуальная база B, static_cast выполняет downcast. Такой static_cast не выполняет проверки времени выполнения , чтобы гарантировать, что тип времени выполнения объекта фактически равен D, и может использоваться только безопасно, если это условие гарантировано другими способами, например при реализации статического полиморфизма. Safe downcast может быть сделано с dynamic_cast.

dynamic_cast < new_type> (выражение)

5) Если выражение представляет собой указатель или ссылка на полиморфного типа Base, и new_type является указателем или ссылкой на тип Derived бегом -time проверка:

a) Самый производный o bject указал/идентифицирован выражение is рассмотрено.Если в этом объекте, выражение точки/относится к общественному основанию Derived, и если только один подобъект Derived типа является производным от подобъекта указала/идентифицирована выражением, то результат из точек литых/относится к этому объекту Derived. (Это известно как "опущенный".)

[...]

с) В противном случае, проверка выполнения терпит неудачу. Если для указателей используется dynamic_cast, возвращается нулевое значение указателя типа new_type. Если он использовался в ссылках, исключается исключение std::bad_cast.

Последнее условие является то, что делает dynamic_cast безопаснее, так как вы можете проверить, если бросок был неудачным:

Base* b1 = new Base; 
if(Derived* d = dynamic_cast<Derived*>(b1)) 
{ 
    std::cout << "downcast from b1 to d successful\n"; 
    d->name(); // safe to call 
}