在QObject *和void *之间转换

时间:2016-09-20 10:53:16

标签: c++ qt pointers casting

我正在使用QT 5.7,由于我必须使用的库,我需要将一个QObject(的派生类)转换为void指针。

几个定义。我有一个只接受void指针的函数,我的类派生自QObject:

void oneFunction(void *obj);

class MyObj : public QObject
{
    ...
};

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

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

在某些时候我将它转换为void指针,因为我必须将它传递给函数。此演员表自动完成:

oneFunction(ptr);

然后,过了一段时间,我收到了我传递的指针,我需要将它转换回原来的类。该函数未修改指针:

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

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

谢谢

2 个答案:

答案 0 :(得分:5)

我认为单static_cast就足够了。

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

如果目标类型已知

static_cast或C风格的演员阵容是可以的。虽然C风格的演员阵容在这里很好用,但不推荐使用,因为:

  • 编译器不会检查C样式的强制转换,而static_cast是。
  • static_cast更具可读性,可以更轻松地进行搜索。
  • More info

如果目标类型未知

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

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

    关于动态投射void*,允许投射但不投射。

在您的情况下void*没有RTTI,因此qobject_castdynamic_cast都不能使用。

答案 1 :(得分:3)

如果 只有,如果您确定指针不是,oneFunction(void*)将永远不会触及指针Undefined,然后在你的程序的其他地方接受该指针的安全性,并将其输入回QObject。请参阅this

在这种情况下,这是完全有效的:

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