Здорова господа!
Я тут решил разобраться с такой операцией как dynamic_cast(). Что это за фигня такая мне не ясно. Я примерно понял это как бы функция которой мы передаем указатель и которая проверяет этот указатель принадлежит ли он принадлежит ли он типу указателю который мы хотим присвоит. Запутано все как то так. Но щас будем разбирать и я думаю по ходу дела все не ясное станет ясным.
Так господа я вроде разобрал dynamic_cast(), что это такое, это такая штука которая позволяет определять для полиморфных типов данных именно конкретный тип. От например у нас есть базовый класс А, и есть два производных класса от него B и С. И есть допустим функция func(A&) в которой нужно передать именно тип класса B, но функция может принимать любой другой тип, производный от класса, А. Как же нам сделать проверку? Для этого существует dynamic_cast(). Мы просто в функции funk(A&) делаем отак:
1 |
B& my_o=dynamic_cast<B&>(o); |
Отакую от небольшую строчечку прописываем, то есть мы преобразуем как бы ссылку A& o к ссылке на тип B& my_o, Если ссылка A& o не типа B&, то генерируется исключение bad_cast, которое мы обрабатываем. Вот примерчик кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
//primeru c dynamic_cast() #include <iostream> using std::cout; using std::endl; #include <exception> using std::exception; class A { virtual void polimorf(){} }; class B : public A { public: void print() { cout <<"fynkci9 print iz klacca B"<<endl; } }; class C : public A {}; void funk(A& o) { try { B& my_o=dynamic_cast<B&>(o); my_o.print(); } catch(exception& e) { cout <<e.what()<<endl; cout <<" ne 9vl9etc9"<<endl; } } int main() { B p; funk(p); cout <<endl<<endl; C ck; funk(ck); return 0; } |
Как видим мы в funk() передали объект типа C : public A и у нас выбросило исключение bad_cast которое мы успешно обработали. Так, что так.
Теперь создадим пример для указателей. Предыдущий пример был для ссылок. dynamic_cast для указателей уже если указатель не может быть преобразован к нужному типу не генерирует исключение, а просто присваивает указателю ноль. От небольшой примерчик по подобию первого примера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
//primeru c dynamic_cast() #include <iostream> using std::cout; using std::endl; #include <exception> using std::exception; #include <cstdlib> using std::exit; class A { virtual void polimorf(){} }; class B : public A { public: void print() { cout <<"fynkci9 print iz klacca B"<<endl; } }; class C : public A {}; void my_funk(A* o) { B* my_o=dynamic_cast<B*>(o); if(my_o!=0) { my_o->print(); } else { cout <<"proizowka owibka my_o ne ykazatel6 na B*"<<endl; exit(1); } } int main() { B* p=new B; my_funk(p); cout <<endl<<endl; C* ck=new C; my_funk(ck); return 0; } |
Как мы видим когда мы функции my_funk() передаем указатель на тип C у нас вызывается блок else выводится сообщение об ошибке и останавливается программа, то есть указателю my_o присвоилось значение ноль.
[youtube]http://www.youtube.com/watch?v=glvMMfmIQIA[/youtube]