Приведение 1-го производного класса ко 2-му производному классу - Почему это работает? - PullRequest
1 голос
/ 07 октября 2019

Я просто создал два производных класса из базового класса. Затем создали объект производного класса и преобразовали в базовый класс. Затем из базового класса я перешел в производный класс номер два, я надеялся, что это не сработает, но это сработало. Может кто-нибудь, пожалуйста, объясните мне, как работает приведенный ниже код ... И как мне предотвратить это ...

PS: Теперь отредактировал Программу, чтобы сделать ее более понятной. Также это ситуация, которую я хочу избежать, если это возможно:

class Animal
{
public:
    Animal() { std::cout << "I am an animal\r\n";  };
    virtual void makeSound() = 0;
    ~Animal() = default;
};

class Cat : public Animal
{
public:
    Cat() { std::cout << "I am a Cat\r\n"; };
    void makeSound() final { std::cout << "Meaow\r\n"; }
    ~Cat() = default;
};

class Dog : public Animal
{
public:
    Dog() { std::cout << "I am a Dog\r\n"; };
    void makeSound() final { std::cout << "Bark\r\n"; }
    ~Dog() = default;
};

template<typename baseType, typename derivedType>
std::unique_ptr<derivedType> dynamicConvert(std::unique_ptr<baseType> baseObj)
{
    auto tmp = dynamic_cast<derivedType*>(baseObj.get());
    std::unique_ptr<derivedType> derivedPointer;
    if (tmp != nullptr)
    {
        baseObj.release();
        derivedPointer.reset(tmp);
    }
    return derivedPointer;
}

int main()
{
    auto cat = std::make_unique<Cat>();
    auto base = dynamicConvert<Cat, Animal>(std::move(cat));
    base->makeSound();
    auto dog = dynamicConvert<Animal, Dog>(std::move(base));
    dog->makeSound();
    return 0;
}

Вывод:

I am an animal
I am a Cat
Meaow
Bark

1 Ответ

3 голосов
/ 07 октября 2019

Вы не можете, это часть контракта с static_cast. Он разрешается во время компиляции и, следовательно, не будет проверять во время выполнения, что вы не допустили ошибку: приведение к неправильному типу просто вызывает UB.

Используйте dynamic_cast, если вы хотите проверенные во время выполнения преобразования.

...