frarugi87 frarugi87 - 2 months ago 15
C++ Question

Converting between QObject* and void*

I'm using QT 5.7 and, because of the libraries I have to use, I need to convert a QObject ('s derived class) to and from a void pointer.

A couple of definitions. I have a function that accepts only a void pointer, and my class derives from QObject:

void oneFunction(void *obj);

class MyObj : public QObject
{
...
};


Then I create and fill an object:

MyObj *ptr = new MyObj(parent);
ptr->.......


At some point I convert it to a void pointer, because I have to pass it to the function. This cast is done automatically:

oneFunction(ptr);


Then, after some time, I receive back the pointer I passed, and I need to convert it back to the original class. The pointer was not modified by the function:

void callbackFromOneFunction(void *theOldPointer)
{
MyObj *oldPtr = qobject_cast<MyObj*>(static_cast<QObject*>(theOldPointer));
if (oldPtr != nullptr)
{
... Now it's back, so use it
}
}


Now, is this whole procedure right? Is there some problem/leak you spot? Is there a better solution?

Thank you

Answer

I think a single static_cast is enough.

static_cast doesn't check the type at runtime and should be used when you're sure the type is okay. In this case you're sure, and you won't need qobject_cast. qobject_cast checks the type at runtime (it's similar to dynamic_cast).


In case of target type being known

A static_cast or C-style cast is okay. Although C-style cast works fine here, it's not recommended because:

  • C-style casts are't checked by compiler whereas static_casts are.
  • static_casts are far more readable and can be searched for more easily.
  • More info.

In case of target type being unknown

  • When the source type is QObject * or its derivations, a single qobject_cast is enough.

  • If the source type is polymorphic, dynamic_cast is used. In other words, dynamic_cast is used only for polymorphic source types (i.e. classes having at least one virtual function). In such classes, at compile-time we can't determine the most derived type of pointers which point to base classes having virtual methods, only at runtime we can determine them.

    About dynamic casting void*, it's allowed to cast to but not cast from.

In your case void* doesn't have any RTTI, so neither qobject_cast nor dynamic_cast can be used.

Comments