【发布时间】:2015-11-25 13:47:10
【问题描述】:
请帮助我理解奇怪的行为:
当析构函数~MyLogicObject() 正在处理时,我使用从MyObject 到MyLogicObject 的dynamic_cast,但编译器抛出异常: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 部分。
-
“但我确定对象 B 是一个多态类型。”
Class B { int b; };不是多态的。它需要定义或继承至少一个虚拟方法(例如虚拟析构函数)才能具有多态性。但在你的例子中,我认为 B 是否是多态的并不重要。 -
你能发布你的输出吗?
-
您的示例 online 似乎有效。我没有深入研究,但是在销毁期间使用虚函数是特殊的。把事情搞砸是很容易的。
-
尝试测试(甚至阅读)您的代码很烦人,因为您已将其拆分为许多不同的文件,这是完全没有必要的。不需要五个单独的文件来证明问题(即它不是minimal, complete, verifiable example)
标签: c++ exception inheritance virtual dynamic-cast