的dynamic_cast<>失败但static_cast<>作品

时间:2012-07-02 07:59:08

标签: c++ dynamic-cast

在我的项目中,我有一个假设的场景:

  • 1)BaseClass是一个派生自父类IFlow
  • 的接口
  • 2)ChildClass派生自它,即来自Base class
  • 3)在childClass Init函数中,我使用dynamic_cast将IFlow的对象转换为BaseClass,如下所示:

    void ChildClass::init()
    {    
        IFlow* pFlow = someMethod(); //it returns the IFlow object pointer
    
        //this works for static cast but fails for dynamic cast    
        BaseClass *base =  dynamic_cast<BaseClass*>(pFlow) ;
    } 
    

在上面的代码中,dynamic _cast的第二行返回零,但如果dynamic_cast更改为static_cast,则代码按预期工作。 请建议

4 个答案:

答案 0 :(得分:7)

dynamic_cast在两个实例中“无法正常工作”:

  1. 您已经以某种方式编译了没有RTTI的代码。修复您的编译器设置。

  2. dynamic_cast的全部目的是确保演员实际上有效。从孩子到父母的铸造总是有效的,因为某种类型的每个孩子都保证是那种类型(整个“所有的狗都是动物,但不是所有的动物都是狗”)。如果对象实际上不是该子类型,则从父级转换为子级可能会失败。如果您提供的dynamic_cast实际上不是IFlowBaseClass将返回空指针。

    此外,您的static_cast无效。它只返回一个值。如果您使用它,则会导致未定义的行为。所以它只是“有效”,因为它返回了你可以尝试使用的值。

  3. 所以发生了这两件事之一。由于您未向我们提供someMethod的实施。

    ,您可以找到哪一个

答案 1 :(得分:1)

如果喜欢这个?:

class A
{
public:
    A(){a = 0;};
    virtual ~A(){};
protected:
    int a;
};
A *GetAInstance();

class B : public A
{
public:
    B() : A() {b = 1;};
    virtual ~B(){};
protected:
    int b;
};

class C: public B
{
public:
    C() : B() {};
    ~C(){};

    void CheckA()
    {
        A *pA = GetAInstance();
        B *pB = dynamic_cast<B*>(pA);  --> Here pB is NULL.
        B *pB2 = static_cast<B*>(pA);
    };
};

A *GetAInstance()
{
    A *pA = new A();
    return pA;
};

int _tmain(int argc, _TCHAR* argv[])
{
    C *pC = new C();
    pC->CheckA();
    return 0;
}

这是因为您正在尝试将父指针设置为其子指针。在dynamic_cast中它认为它不安全,所以它将子指针设置为NULL,你可以看到上面的pB是NULL。对于子类可能有更多的函数/成员变量,您调用这些新函数/成员变量会导致运行时错误。但是static_cast并不关心这一点,它只是一个编译器时间检查而不是运行时检查。 static_cast只关心它们是否有某种关系。如果有,static_cast转换指针甚至不关心运行时错误。请运行此小样本并检查pB2是否为NULL。 :)

希望有用。谢谢! :)

答案 2 :(得分:0)

someMethod()返回什么类型?它需要从BaseClass派生,以允许dynamic_cast工作。如果不是正确类型,则无法向下投射。

静态强制转换在编译时工作,编译器只会将指针翻转过来。

答案 3 :(得分:0)

如果演员表不合法,dynamic_cast<>将返回null(零)。在这种情况下,它正在执行您想要的操作:继承树中的某个位置存在问题。 (static_cast<>“工作”只是因为它是一个大锤;它在编译时强制执行转换而不知道指针在运行时实际具有的类型。)