c++ - 将第一个派生类转换为第二个派生类 - 为什么它有效?

标签 c++ c++11 dynamic-cast static-cast

我只是从一个基类创建了两个派生类。 然后创建派生类的对象并转换为基类。 然后从基类,我转换为派生类二, 我希望它不会起作用,但它确实起作用了。 有人能解释一下下面的代码是如何工作的吗……我该如何防止这种情况发生……

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

最佳答案

你不能,这是与 static_cast 的契约的一部分。它在编译时解决,因此不会在运行时检查您是否犯了错误:转换为错误的类型只会触发 UB。

当您需要运行时检查的转换时使用dynamic_cast

关于c++ - 将第一个派生类转换为第二个派生类 - 为什么它有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58267495/

相关文章:

c++ - 快速图像处理

c++ - 将 template<derived> 分配给 template<base> 变量

c++ - 在模板中,如果从属名称是函数,则调用它

c++ - 如何在 Mac OS X 中获取 aio 信号处理程序的用户数据

c++ - 当指针作为指向另一个函数内部指针的指针传递时会发生什么?

闭源应用程序的 C++ 压缩 (zip) 库

c++ - 嵌套循环的 OpenMP 偶数/奇数分解

c++ - 何时使用 dynamic_cast 的可接受示例?

c++ - 转换多态智能指针对象

c++ - 如何使用动态转换检测到指针的删除