问题
I'm using Visual Studio and performing a valid dynamic cast. RTTI is enabled.
Edit : Updated the code to be more realistic
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 );
My debugger says that in_ptr is of the correct type when the exception is thrown. Google seems particularly unhelpful. Any ideas? Cheers.
回答1:
I ran a test based on your pseudo-code and it works. So if RTTI is truly enabled in your build configuration, then it must be another problem that isn't captured in what you posted.
回答2:
http://msdn.microsoft.com/en-us/library/fyf39xec(VS.80).aspx has info on __non_rtti_object_exception.
From MSDN:
If the pointer does not point to a valid object, a __non_rtti_objectexception is thrown, indicating an attempt to analyze the RTTI that triggered a fault (like access violation), because the object is somehow invalid (bad pointer or the code wasn't compiled with /GR).
回答3:
RTTI exceptions, failures, or errors around a dynamic_cast can mean that you performed an illegal cast. dynamic_cast<derived*>(ptrToBase)
is valid if and only if class derived
and class base
both meet the following constraint: that class, or one of its base classes, has a virtual member function.
This virtual member function can be anything, including the destructor. If you don't have any other member functions, you can try:
struct base
{
virtual ~base(){}
...
}
struct derived : public base
{
...
}
Now base
has a virtual member function, and so does derived. Try that out and see if it resolves your issue.
EDIT-ADD:
@carleeto -- In "it already had a virtual destructor", doe it==base?
If derived has virtual destructor but base is non-virtual dtor, then you may still get this error.
Also, you should verify that the object hasn't been destructed -- once the destructor runs, dynamic_cast is no longer safe to call. Try adding a trace to the ctors and dtors.
回答4:
Make doubly sure you have RTTI enabled in all source files.
Otherwise the pointer is invalid.
回答5:
Does base
contain any virtual
methods? It must in order for dynamic_cast
to work.
来源:https://stackoverflow.com/questions/854864/when-and-why-is-an-std-non-rtti-object-exception-generated