Пожалуйста, помогите мне понять странное поведение:C++ dynamic_cast исключение
Я использую dynamic_cast от MyObject
к MyLogicObject
, когда деструктор ~MyLogicObject()
в обработке, но компилятор сгенерирует исключение: non_rtti_object
.
Я уверен, что объект MyObject
является полиморфным типом. Где я ошибаюсь?
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <string>
class A
{
int a;
};
class B
{
int b;
};
class MyObject: public A,
public B// if comment this row, and don't use multi inheritable, everything will be fine
{
private: std::string name;
private: bool singleshot;
public: MyObject(void);
public: virtual ~MyObject(void);
protected: void Destroying(void);
public: std::string GetName(void);
public: virtual bool Rename(std::string _newName);
};
#endif
#include "MyObject.h"
#include "MyLogicObject.h"
MyObject::MyObject(void): singleshot(true)
{}
MyObject::~MyObject(void)
{
printf("\n~my object\n");
Destroying();
}
void MyObject::Destroying(void)
{
if(singleshot)
{
printf("\nexception!\n");
dynamic_cast<MyLogicObject*>(this);// exception: non_rtti_object
singleshot = false;
}
}
std::string MyObject::GetName(void)
{
return name;
}
bool MyObject::Rename(std::string _newName)
{
name = _newName;
return true;
}
#ifndef MYLOGICOBJECT_H
#define MYLOGICOBJECT_H
#include "MyObject.h"
class MyLogicObject: public virtual MyObject // if not use virtual inheritance (instead, use the standard inheritance), everything will be fine
{
public: MyLogicObject(void);
public: virtual ~MyLogicObject(void);
public: virtual void Update(float _delta = 0.0f);
// if reimplement virtual method of base class, everything will be fine
/*
public: virtual bool Rename(std::string _newName)
{
return MyObject::Rename(_newName);
}
*/
};
#endif
#include "MyLogicObject.h"
MyLogicObject::MyLogicObject(void)
{}
MyLogicObject::~MyLogicObject(void)
{
printf("\n~my logic object\n");
Destroying();
}
void MyLogicObject::Update(float _delta)
{}
#include <conio.h>
#include <stdio.h>
#include "MyLogicScene.h"
class C
{
int c;
};
class DerivedObject: public MyLogicObject,
public C// if comment this row, and don't use multi inheritable, everything will be fine
{
public: DerivedObject(void)
{}
public: virtual ~DerivedObject(void)
{
printf("~derived object: %s\n", GetName().c_str());
//Destroying(); // if call Destroying in this place, overything will be file
}
};
int main()
{
DerivedObject* object1 = new DerivedObject();
object1->Rename("object1");
printf("delete object1...\n");
delete object1;
getch();
return 0;
}
Изнутри деструктора MyObject уже уничтожил часть объекта MyLogicObject. – qPCR4vir
«Но я уверен, что объект B является типом полиморфа». 'Класс B {int b; }; 'не является полиморфным. Он должен иметь либо определенный, либо унаследованный, по меньшей мере, один виртуальный метод (например, виртуальный деструктор), который должен быть полиморфным. Но в вашем примере я думаю, что неважно, является ли B полиморфным или нет. –
, если вы запустите мой код, вы увидите, что ошибка произошла до того, как закончен файл MyLogicObject. Это значит, что MyLogicObject все еще существует. Кроме того, почему код работает нормально, если вы удаляете наследование класса C? – Gregory