在C ++中使用reinterpret_cast进行向下转换

时间:2016-02-20 15:10:49

标签: c++ c++11 visual-c++

我只是想更详细地了解向下转换,我知道这是不可取的,因为它会导致未定义的运行时行为。我们什么时候真的需要使用羽绒铸造?

还要考虑下传的编码片段和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;
}

1 个答案:

答案 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。