I've got some kind of object factory (template based), that works pretty good for my purposes. But now I've tried to work with class, that derives from both QObject and pure abstract class (interface) and I've got strange run-time errors.
Here the simple picture of this class (Derived)
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();
};
and its implementation in derived.cpp:
#include "derived.h"
Derived::Derived(QObject *parent)
: QObject(parent) {
}
int Derived::getResult() {
return 55;
}
When I try to cast void pointer to the Interface, I'll get unexpected (for me) behavior, it can be or runtime error, or other method call (it depends of classes' size).
#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;
}
Could you explain me why I cannot cast void pointer to interface? And is there any workaround?
Thanks for your responses
Reinterpreting a pointer to a derived class as a pointer to a base class gives undefined behaviour. This is highlighted by multiple inheritance: since there is more than one base class, and the two base subobjects must have different addresses, they can't both have the same address as the derived object. So the pointer returned by your create
function points to a Derived
, but not necessarily to the Interface
subobject. It could point to QObject
subobject, or to neither.
The best option is to return Derived*
or Interface*
from your function; if it must be void*
for some reason, then the only well-defined cast you can make is back to Derived*
, which can then be converted to Interface*
using standard conversions.
By using void*
you have thrown away all static and dynamic knowledge of the type; the only way to restore that information is to cast back to the correct type.