Как использовать dynamic_cast в операторе if - PullRequest
0 голосов
/ 03 июля 2018

Итак, у меня есть простое задание. Есть 3 класса, полученные из одного базового класса. Они довольно просты и будут представлены ниже. Мне нужно создать новый класс с именем PolymorphicAnimal, который будет вести себя так же, как любой другой animal, производный от базового класса Animal. Чтобы быть точным, все, что им нужно сделать, это отобразить правильный текст после вызова метода SoundOff. Я предполагаю, что мне нужно использовать dynamic_cast здесь. Мой вопрос заключается в том, каков правильный синтаксис для использования dynamic_cast в качестве оператора if, и все ли производные классы должны иметь хотя бы один виртуальный метод?

#include "stdafx.h"
#include <iostream>
#include <string>

class Animal {
public:
virtual std::string SoundOff() = 0;
};

class Dog : public Animal {
std::string SoundOff() override { return "Woof"; }
};

class Cat : public Animal {
std::string SoundOff() override { return "Meow"; }
};

class Cow : public Animal {
std::string SoundOff() override { return "Muu"; }
};

class PolymorphicAnimal : public Animal {
std::string sound;
public:
PolymorphicAnimal(const Animal &a) {
    if(std::dynamic_cast<Cat*>(a))
}
};

Строка if(std::dynamic_cast... генерирует ошибки компилятора:

syntax error '<', illegal token on the right side of :: и expected an identifier

Ответы [ 4 ]

0 голосов
/ 03 июля 2018

Очень неясно, что именно должен делать PolymorphicAnimal. Как-то нужно рассказать PolymorphicAnimal, как себя вести, верно? Итак, я предполагаю, что это больше похоже на Factory, чем на производный класс.

Примерно так:

class PolymorphicAnimal : Animal
{
private:
    Animal *animal;
public:
    PolymorphicAnimal(int type)
    {
        if (type == Type_Cat) // Type_Cat is an enum for example
        {
            animal = new Cat();
        }
        // ...add other types here
    }
    std::string SoundOff()
    {
        return animal->SoundOff();
    }
}

Обычно вам не нужно делать if (что-то dynamic_cast что-то) в обычной программе.

0 голосов
/ 03 июля 2018

В то время как виртуальные методы или посетитель могут быть более подходящими, вы можете использовать что-то вроде:

PolymorphicAnimal(const Animal &a) {
    if (const auto* cat = dynamic_cast<const Cat*>(&a)) {
        // use cat
    } else if (const auto* dog = dynamic_cast<const Dog*>(&a)) {
        // use dog
    } // ...
}
0 голосов
/ 03 июля 2018

dynamic_cast - это почти всегда взлом.

Почему бы вам не добавить еще один виртуальный метод в Animal, а затем Dog, Cat и Cow переопределить его обычным способом? Или вы не контролируете эти классы?

0 голосов
/ 03 июля 2018

В C ++ вы можете объявить переменную в условном выражении if, что является мощной функцией, которую вы можете использовать здесь. Таким образом,

if (auto kitty = dynamic_cast<const Cat*>(&a)){
    // kitty is not nullptr
}

Примечания:

  1. dynamic_cast - это ключевое слово ; бросьте std::
  2. Я использовал указатель dynamic_cast. Эталонная альтернатива нецелесообразна, так как в общем случае вы не можете ожидать неявного преобразования ссылочного типа в тип bool, и в случае неудачного приведения ссылки генерируется исключение.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...