использование dynamic_cast для идентификации типа во время выполнения

при чтении Essential c ++, глава 5.10 Идентификация типа во время выполнения, я столкнулся с проблемой. Позвольте мне представить немного фона в первую очередь. Есть базовый класс с именем num_sequence и класс Fibonacci вытекают из num_sequence, В базовом классе есть виртуальная функция с именем gen_elems и производный класс имеет свое собственное определение.

Следующее происходит из книги.

Fibonacci fib;
num_sequence *ps = &fib;
ps->gen_elems(64);

Мы знаем, что будет вызван экземпляр Фибоначчи gen_elems ().
Однако, хотя мы знаем из этого теста, что PS обращается к Фибоначчи
объект класса, попытка вызвать экземпляр Фибоначчи
gen_elems () напрямую через ps приводит к ошибке времени компиляции:

PS-> Фибоначчи :: gen_elems (64); // выдает ошибку во время компиляции

ps не знает тип объекта, к которому обращается, даже если мы, механизмы typeid и виртуальные функции знаем.

Чтобы вызвать экземпляр gen_elems () Фибоначчи, мы должны указать компилятору преобразовать ps в указатель типа Фибоначчи. Static_cast и dynamic_cast могут выполнять эту работу.

Я смущен смелым предложением. ps->gen_elems(64) на самом деле вызывает экземпляр Фибоначчи gen_elems(), Зачем нам использовать static_cast и dynamic_cast для преобразования его в указатель типа Fibonacci?

0

Решение

Под самый В таких ситуациях вы просто вызываете виртуальный метод обычным образом и позволяете полиморфизму выполнять свою работу для вызова самой производной реализации по мере необходимости. Автор пытается объяснить, что также можно напрямую вызвать конкретный реализация виртуального метода без прохождения полиморфизма.

Скажем, класс происходит от Fibonacci переопределить gen_elems() снова, но вы не хотите вызывать это переопределение, вы хотите вызвать Fibonacci переопределения. Преобразовав num_sequence указатель на Fibonacci указатель (или указатель потомка) во время компиляции, он позволяет компилятору получить доступ к Fiboncci vtable, чтобы он мог выдавать код для прямого вызова Fibonacci::gen_elems() (если объект, на который указывают во время выполнения, на самом деле не является экземпляром Fibanocci или потомок, вы, скорее всего, сломаете / испортите ваше приложение. Это не может быть проверено во время компиляции).

Например:

class num_sequence
{
public:
virtual void gen_elems(int value)
{
std::cout << "num_sequence" << std::endl;
}
};

class Fibonacci : public num_sequence
{
public:
void gen_elems(int value)
{
std::cout << "Fibonacci" << std::endl;
}
};

class SomethingElse : public Fibonacci
{
public:
void gen_elems(int value)
{
std::cout << "SomethingElse" << std::endl;
}
};

.

num_sequence ns;
Fibonacci fib;
SomethingElse se;
num_sequence *ps;

ps = &ns;
ps->gen_elems(64); // displays "num_sequence"
ps = &fib;
ps->gen_elems(64); // displays "Fibonacci"
ps = &se;
ps->gen_elems(64); // displays "SomethingElse"
ps->Fiboacci::gen_elems(64); // compiler error!

static_cast<Fibonacci*>(ps)->Fibonacci::gen_elems(64); // displays "Fibonacci"static_cast<SomethingElse*>(ps)->Fibonacci::gen_elems(64); // displays "Fibonacci"
Fibonacci *pfib = dynamic_cast<Fibonacci*>(ps);
if (pfib != NULL)
{
pfib->gen_elems(64); // displays "SomethingElse"pfib->Fibonacci::gen_elems(64); // displays "Fibonacci"}
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]