何时以及为什么生成std :: __ non_rtti_object异常?

时间:2009-05-12 21:02:11

标签: c++ exception visual-studio-2005 rtti

我正在使用Visual Studio并执行有效的动态转换。 RTTI已启用。

编辑:更新代码更加真实

struct base
{
    virtual base* Clone()
    {
        base* ptr = new base;
        CopyValuesTo( ptr );
        return ptr;
    }
    virtual void CopyValuesTo( base* ptr )
    {
       ...
    }
    virtual ~base()
    {
    }
}

struct derived : public base
{
    virtual base* Clone()
    {
        derived* ptr = new derived;
        CopyValuesTo( ptr );
        return ptr;
    }
    virtual void CopyValuesTo( base* ptr )
    {
       ...
    }
    virtual ~derived()
    {
    }
}  

void Class1::UseNewSpec( base* in_ptr ) //part of a totally unrelated class
{
    derived* ptr = dynamic_cast<derived *>(in_ptr);
    if( !ptr )
       return;
    delete m_ptr;
    m_ptr = ptr->Clone(); //m_ptr is a member of Class1 of type base*
}

//usage : 
Class1 obj;
derived new_spec; 
obj.UseNewSpec( &new_spec );

我的调试器表示在抛出异常时in_ptr的类型正确。谷歌似乎特别无益。有任何想法吗?欢呼声。

5 个答案:

答案 0 :(得分:8)

http://msdn.microsoft.com/en-us/library/fyf39xec(VS.80).aspx有__non_rtti_object_exception的信息。

来自MSDN:

  

如果指针未指向a   有效对象,抛出__non_rtti_objectexception,表示   试图分析RTTI   触发了一个错误(如访问   违规),因为对象是   某种程度上无效(坏指针或   代码未使用/ GR编译。

答案 1 :(得分:5)

围绕dynamic_cast的RTTI异常,失败或错误可能意味着您执行了非法转换。当且仅当类dynamic_cast<derived*>(ptrToBase)和类derived都满足以下约束时,base才有效:该类或其基类之一具有虚拟成员函数。

这个虚拟成员函数可以是任何东西,包括析构函数。如果您没有任何其他成员函数,可以尝试:

struct base
{
    virtual ~base(){}
    ...
}

struct derived : public base
{
    ...
}

现在base有一个虚拟成员函数,派生也是如此。试试看,看看它是否能解决你的问题。

EDIT-ADD:

@carleeto - 在“它已经有一个虚拟析构函数”中,它是= =基数?

如果派生有虚拟析构函数但base是非虚拟dtor,那么您可能仍然会收到此错误。

此外,您应该验证对象是否已被破坏 - 一旦析构函数运行,dynamic_cast就不再安全。尝试在ctors和dtors中添加一条迹线。

答案 2 :(得分:5)

我根据你的伪代码进行了测试,但它确实有效。因此,如果在构建配置中真正启用了RTTI,那么它必然是您发布的内容中未捕获的另一个问题。

答案 3 :(得分:1)

确保在所有源文件中都启用了RTTI。

否则指针无效。

答案 4 :(得分:0)

base是否包含任何virtual方法?必须使dynamic_cast能够正常工作。