我正在使用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的类型正确。谷歌似乎特别无益。有任何想法吗?欢呼声。
答案 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
能够正常工作。