Pan*_*nch 1 c++ visual-c++ c++11
我只是想更详细地了解向下转换,我知道这是不可取的,因为它会导致未定义的运行时行为。我们什么时候真的需要使用向下转换?
还要考虑向下转换的编码片段和 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;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
向下转型本身不会导致未定义的行为。如果您有指向 base 的指针或引用,则可以使用 dynamic_cast 并确保它仅在它确实是派生的情况下才有效。如果它不是派生的,您将获得 nullptr 或异常(在转换引用时)。一切都将在运行时检查。
如果您已经知道您的基指针是派生的,则可以改用 static_cast。但是,不会执行任何检查,因此您可能会导致基指针的未定义行为不是派生的。
reinterpret_cast 不应用于向下转换。与 static_cast 一样,不会执行运行时检查,也不会执行编译时检查。您可能会意外地跨继承树进行转换(例如,从 base 到 other_base)。对于单继承的情况,reinterpret_cast 将像 static_cast 一样工作,但是当使用多重继承时,reinterpret_cast 不会修改指向对象内部正确基数的指针,并且您有未定义的行为。
当您可以使用 static_cast 时,我建议您远离 reinterpret_cast。