2012-07-02 32 views
4

在我的项目我有一个假设一个场景:的dynamic_cast <>失败,但的static_cast <>工作

  • 1)BaseClass的是从父类IFlow
  • 2)ChildClass提炼出来的派生的接口即,从基类
  • 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的第二行返回0,但如果dynamic_cast更改为static_cast,那么代码将按预期工作。 请指教

回答

0

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

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

0

如果转换不合法,则A dynamic_cast<>返回null(零)。在这种情况下,它正在做你想做的事情:在继承树的某处存在问题。 (该static_cast<>“工程”不仅是因为它是一个大锤,它迫使在编译时的转换,不指针实际上将有在运行时类型的知识。)

7

dynamic_cast会在两种情况下“不工作”:

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

  2. dynamic_cast的整个目的是为了确保该演员实际上工作。从孩子到父母的投射总是有效的,因为某种类型的每个孩子都保证是那种类型(整个“所有的狗都是动物,但并非所有的动物都是狗”)。如果对象实际上不是该子类型,则从父项到子项的转换可能会失败。如果你给它的IFlow实际上不是BaseClass,则dynamic_cast将返回空指针。您的static_cast不起作用。它只是返回一个值。一个值,如果您曾经使用它,导致未定义的行为。所以它只是“起作用”,因为它返回了一个你可以尝试使用的值。

所以发生了这两件事之一。你可以找到哪一个,因为你没有给我们执行someMethod

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的pB。对于子类可能有更多的函数/成员变量,你调用这些新的函数/成员变量会导致运行时错误。但static_cast不关心这个,它只是一个编译器时间检查不运行时间检查。 static_cast只关心他们是否有关系。如果他们有,static_cast转换指针,即使不关心运行时错误。请运行这个小样本,并检查pB2不是NULL。 :)

希望有用。谢谢! :)

相关问题