在QObject *和void *之间转换

fra*_*i87 3 c++ qt pointers casting

我正在使用QT 5.7,并且由于必须使用库,因此需要将QObject(派生类)与void指针进行相互转换。

几个定义。我有一个仅接受空指针的函数,而我的类是从QObject派生的:

void oneFunction(void *obj);

class MyObj : public QObject
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

然后创建并填充一个对象:

MyObj *ptr = new MyObj(parent);
ptr->.......
Run Code Online (Sandbox Code Playgroud)

在某些时候,我将其转换为void指针,因为我必须将其传递给函数。该转换是自动完成的:

oneFunction(ptr);
Run Code Online (Sandbox Code Playgroud)

然后,一段时间后,我收到了我传递的指针,并且需要将其转换回原始类。指针未被函数修改:

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

现在,整个过程对吗?您发现一些问题/泄漏吗?有更好的解决方案吗?

谢谢

fro*_*tto 5

我认为一个static_cast就足够了。

static_cast不会在运行时检查类型,应该在确定类型可以使用时使用。在这种情况下,您可以确定并且不需要qobject_cast。qobject_cast在运行时检查类型(类似于dynamic_cast)。


如果目标类型已知

A static_cast或C样式的转换也可以。尽管C样式强制转换在这里可以正常工作,但不建议这样做,因为:

  • 编译器不检查C样式的类型转换,而static_casts进行检查。
  • static_casts更具可读性,可以更轻松地进行搜索。
  • 更多信息。

如果目标类型未知

  • 当源类型是QObject *或其派生类型时,单个qobject_cast就足够了。

  • 如果源类型是多态的,dynamic_cast则使用。换句话说,dynamic_cast使用仅用于多态源类型(具有至少一个虚拟函数即类)。在这样的类中,在编译时我们无法确定指向具有虚拟方法的基类的指针的最大派生类型,只有在运行时才能确定它们。

    关于动态转换void*,可以将其强制转换为但不能从其强制转换。

在您的情况下void*,没有任何RTTI,因此qobject_cast也dynamic_cast无法使用。