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
createfunction points to aDerived, but not necessarily to theInterfacesubobject. It could point toQObjectsubobject, or to neither.The best option is to return
Derived*orInterface*from your function; if it must bevoid*for some reason, then the only well-defined cast you can make is back toDerived*, which can then be converted toInterface*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.