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

C++ 将第一个派生类转换为第二个派生类-为什么有效?,c++,c++11,dynamic-cast,static-cast,C++,C++11,Dynamic Cast,Static Cast,我只是从一个基类创建了两个派生类。 然后创建派生类的对象并转换为基类。 然后从基类转换为派生类2, 我希望它不会起作用,但它确实起了作用。 谁能解释一下下面的代码是如何工作的。。。我该如何防止这种情况发生 PS:现在编辑这个程序,让它更有意义。 如果可能的话,这也是我想要避免的情况: class Animal { public: Animal() { std::cout << "I am an animal\r\n"; }; virtual void makeSou

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

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;
}

你不能,这是静态演员合同的一部分。它是在编译时解决的,因此不会在运行时检查您是否犯了错误:转换到错误的类型只会触发UB


当您需要运行时检查的转换时,请使用动态转换。

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


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

但这会编译并运行,并给出kinna预期的结果这是基类这是派生的2类打印class@NovoiceProgrammer该计划的行为符合你的期望仅仅是运气或缺乏运气,并不意味着它是正确的。根据定义,您可能会从具有未定义行为的程序中体验到任何结果。但这会编译并运行,并给出kinna预期的结果这是基类这是派生的2类打印class@NovoiceProgrammer该计划的行为符合你的期望仅仅是运气或缺乏运气,并不意味着它是正确的。根据定义,您可能会从具有未定义行为的程序中体验到任何结果。可能重复可能重复
I am an animal
I am a Cat
Meaow
Bark