4

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

  • 1) BaseClass 是从父类 IFlow 派生的接口
  • 2) ChildClass 派生自它,即从 Base 类
  • 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

4 回答 4

8

dynamic_cast在两种情况下将“不起作用”:

  1. 您以某种方式在没有 RTTI 的情况下编译了您的代码。修复编译器设置。

  2. 的全部目的dynamic_cast确保演员阵容确实有效。从孩子到父母的转换总是有效的,因为保证某种类型的每个孩子都是那种类型(整个“所有的狗都是动物,但并非所有的动物都是狗”的事情)。如果对象实际上不是该子类型,则从父级转换为子级可能会失败。dynamic_cast如果IFlow你给它的实际上不是一个BaseClass.

    此外,你的static_cast不起作用。它只是返回一个值。一个值,如果你曾经使用它,会导致未定义的行为。因此,它仅在返回一个您可以尝试使用的值的意义上“起作用”。

所以这两件事中的一件发生了。哪一个由您决定,因为您没有向我们提供someMethod.

于 2012-07-02T08:09:19.517 回答
1

dynamic_cast<>如果强制转换不合法,则A返回 null(零)。在这种情况下,它正在做你想做的事:在你的继承树的某个地方有问题。(static_cast<>“有效”只是因为它是一把大锤;它在编译时强制强制转换,而不知道指针在运行时实际具有的类型。)

于 2012-07-02T08:08:21.200 回答
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。:)

希望有用。谢谢!:)

于 2012-07-02T08:25:44.747 回答
0

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

静态转换在编译时起作用,编译器只会翻转指针。

于 2012-07-02T08:03:28.050 回答