【问题标题】:Converting between QObject* and void*在 QObject* 和 void* 之间转换
【发布时间】:2016-09-20 10:53:15
【问题描述】:

我正在使用 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
    }
}

现在,整个过程正确吗?您是否发现了一些问题/泄漏?有没有更好的解决方案?

谢谢

【问题讨论】:

  • 如果通过隐式转换从MyObj* 转换为void*,则需要将static_cast 转换回MyObj*,而不是QObject*。仅当类型完全相同时才能保证往返。

标签: c++ qt pointers casting


【解决方案1】:

我认为单个static_cast 就足够了。

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


如果目标类型已知

static_cast 或 C 风格的演员表是可以的。虽然 C 风格的转换在这里可以正常工作,但不推荐这样做,因为:

  • 编译器不检查 C 样式转换,而 static_casts 是。
  • static_casts 的可读性更高,更容易搜索。
  • More info

目标类型未知时

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

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

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

在您的情况下,void* 没有任何 RTTI,因此既不能使用 qobject_cast 也不能使用 dynamic_cast

【讨论】:

  • 解决方案 2(仅 qobject_cast)的问题是 qobject_cast 需要 QObject*,而不是 void*,所以单个是不够的
  • 应该避免 C 风格的转换。
  • @rubenvb 你是对的。为了可读性和编译器检查,static_cast 优于 C 样式转换。更新了我的答案。
  • 它们也不等同:C 风格的转换仍然与任何 c++ 转换完全不同,请参阅this answer
  • @rubenvb 我没有说它们是等价的。我说过这两种转换都有效,即使强烈建议不要在 C++ 中使用 C 风格转换。
【解决方案2】:

如果 并且如果您确定指针没有并且永远不会被oneFunction(void*)以@987654321的方式触摸@,然后在你的程序的其他地方接收该指针并将其类型转换回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
    }
}

【讨论】:

    猜你喜欢
    • 2021-02-28
    • 2023-03-17
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2013-02-13
    • 2021-09-29
    • 2014-09-05
    • 2015-09-26
    相关资源
    最近更新 更多