Предыдущий пост -
Следующий пост -

Операция dynamic_cast().

Рубрика: C++, Дата: 16 April, 2013, Автор:

Здорова господа!

Я тут решил разобраться с такой операцией как dynamic_cast(). Что это за фигня такая мне не ясно. Я примерно понял это как бы функция которой мы передаем указатель и которая проверяет этот указатель принадлежит ли он принадлежит ли он типу указателю который мы хотим присвоит. Запутано все как то так. Но щас будем разбирать и я думаю по ходу дела все не ясное станет ясным.

Так господа я вроде разобрал dynamic_cast(), что это такое, это такая штука которая позволяет определять для полиморфных типов данных именно конкретный тип. От например у нас есть базовый класс А, и есть два производных класса от него B и С. И есть допустим функция func(A&) в которой нужно передать именно тип класса B, но функция может принимать любой другой тип, производный от класса, А. Как же нам сделать проверку? Для этого существует dynamic_cast(). Мы просто в функции funk(A&) делаем отак:

B& my_o=dynamic_cast<B&>(o);

Отакую от небольшую строчечку прописываем, то есть мы преобразуем как бы ссылку A& o к ссылке на тип B& my_o, Если ссылка A& o не типа B&, то генерируется исключение bad_cast, которое мы обрабатываем. Вот примерчик кода:

//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 для указателей уже если указатель не может быть преобразован к нужному типу не генерирует исключение, а просто присваивает указателю ноль. От небольшой примерчик по подобию первого примера:

//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]

rss