将第一个派生类转换为第二个派生类 - 为什么有效?
Casting 1st Derived Class to 2nd Derived Class - Why does it work?
我只是从一个基类创建了两个派生类。 然后创建派生类的对象并转换为基类。 然后从基类,我转换为派生类二, 我希望它不会起作用,但它确实起作用了。 有人可以解释一下下面的代码是如何工作的......以及我如何防止这种情况发生...
PS:现在编辑了程序以使其更有意义。 如果可能的话,这也是我想避免的情况:
class Animal
{
public:
Animal() { std::cout << "I am an animalrn"; };
virtual void makeSound() = 0;
~Animal() = default;
};
class Cat : public Animal
{
public:
Cat() { std::cout << "I am a Catrn"; };
void makeSound() final { std::cout << "Meaowrn"; }
~Cat() = default;
};
class Dog : public Animal
{
public:
Dog() { std::cout << "I am a Dogrn"; };
void makeSound() final { std::cout << "Barkrn"; }
~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
。
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 为什么此派生对象无法访问基类的后递减方法?
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 为什么派生类的好友不能使用受保护的成员?
- C++:为什么无法在派生类中访问受保护的构造函数?
- 为什么基类数据在派生类数据之前初始化
- 为什么为派生类定义复制构造函数需要定义基类的默认构造函数?
- 为什么基类中的复制和交换会导致派生类中的复制赋值运算符被隐式删除?
- 为什么编译器C++不能知道指针指向派生类?
- 为什么从基转换为派生提供此功能?
- 为什么派生类的实例从基类调用方法?
- 为什么允许将派生类的方法static_cast为基类的方法?
- C++ 为什么要将对基类的引用传递给派生类的构造函数
- 为什么此代码不将基类强制转换为 c++ 中的派生类?
- CRTP:为什么获得嵌套类型和派生类的嵌套方法有区别
- 为什么不能在实例化对基类的引用的同时实例化指向派生类的指针?
- 将第一个派生类转换为第二个派生类 - 为什么有效?
- 为什么"运算符<<"不适用于指向派生类型的成员?
- 在C++中,为什么仅包含与其基类实例的联合的派生类占用的内存多于联合的大小?
- 双重派生 - 为什么需要铸造