我有某种对象工厂(基于模板),它非常适合我的目的。但现在我尝试使用从 QObject 和纯抽象类(接口(interface))派生的类,并且我遇到了奇怪的运行时错误。
这是该类的简单图片(派生)
class Interface {
public:
Interface(){}
virtual ~Interface(){}
virtual int getResult() = 0;
};
class Derived : public QObject, public Interface {
Q_OBJECT
public:
explicit Derived(QObject *parent = 0);
int getResult();
};
及其在derive.cpp中的实现:
#include "derived.h"
Derived::Derived(QObject *parent)
: QObject(parent) {
}
int Derived::getResult() {
return 55;
}
当我尝试将 void 指针转换为接口(interface)时,我会得到意外的(对我来说)行为,它可能是运行时错误,或其他方法调用(这取决于类的大小)。
#include "derived.h"
void * create() {
return new Derived();
}
int main(int argc, char *argv[]) {
Interface * interface = reinterpret_cast<Interface *>(create());
int res = interface->getResult(); // Run-time error, or other method is called here
return 0;
}
你能解释一下为什么我不能将 void 指针转换为接口(interface)吗?有什么解决办法吗?
感谢您的回复
最佳答案
将指向派生类的指针重新解释为指向基类的指针会产生未定义的行为。多重继承突出了这一点:由于有多个基类,并且两个基子对象必须具有不同的地址,因此它们不能都与派生对象具有相同的地址。因此,create
函数返回的指针指向 Derived
,但不一定指向 Interface
子对象。它可以指向 QObject
子对象,也可以都不指向。
最好的选择是从函数返回 Derived*
或 Interface*
;如果由于某种原因它必须是 void*
,那么您可以进行的唯一明确定义的转换就是返回 Derived*
,然后可以将其转换为 Interface *
使用标准转换。
通过使用void*
,您已经抛弃了该类型的所有静态和动态知识;恢复该信息的唯一方法是转换回正确的类型。
关于c++ - reinterpret_cast 到 QObject 的同级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14459889/