我只是想更详细地了解向下转换,我知道这是不可取的,因为它会导致未定义的运行时行为。我们什么时候真的需要使用羽绒铸造?
还要考虑下传的编码片段和dynamic_cast返回,但是当我使用reinterpret_cast时,它会正确地打印出派生类函数,如何?只有在按值分配对象而不是通过引用或指针分配对象时,对象切片才会生效?
#include <iostream>
using namespace std;
class base
{
public:
void func1()
{
std::cout<<"\n Base Function"<<std::endl;
}
virtual ~base(){cout<<"\n Base Destructor"<<endl;}
};
class derived:public base
{
public:
void func2()
{
std::cout<<"\n Derived Function"<<std::endl;
}
};
int main()
{
base *ptr = dynamic_cast<base*>(new derived); // Up casting
if (ptr)
{
ptr->func1();
}
else
{
cout<<"\n casting failed"<<endl;
}
derived *ptr1 = dynamic_cast<derived*>(new base); // Down casting
if (ptr1)
{
ptr1->func2();
}
else
{
cout<<"\n ptr1 casting failed"<<endl;
}
return 0;
}
答案 0 :(得分:2)
向下转换本身并不会导致未定义的行为。如果你有一个指向base或base的引用,你可以使用dynamic_cast并确保它只有在它真正是派生时才有效。如果它不是派生的,您将获得nullptr或异常(在转换引用时)。一切都将在运行时进行检查。
如果您已经知道您的基指针是派生的,那么您可以使用static_cast。但是,不会执行任何检查,因此您可能导致基本指针的未定义行为不是派生的。
reinterpret_cast不应该用于向下转换。与static_cast一样,不会执行运行时检查,也不会执行编译时检查。您可能会意外地跨越继承树(例如从base到other_base)。 对于单继承的情况,reinterpret_cast将像static_cast一样工作,但是当使用多继承时,reinterpret_cast不会修改指向对象内部正确基础的指针,并且您有未定义的行为。
我建议您在使用static_cast时远离reinterpret_cast。