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.
https://learn.microsoft.com/en-us/cpp/cpp/typeid-operator?view=vs-2019 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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With