为什么Qt使用reinterpret_cast而不是static_cast来处理void*?

5

您可以使用static_cast将任何指向T的指针转换为/从void*,那么为什么Qt使用reinterpret_cast呢?

int SOME_OBJECT::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QMainWindow::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        // Why reinterpret_cast here??
        case 0: on_tabWidget_tabCloseRequested((*reinterpret_cast< int(*)>(_a[1]))); break;
        default: ;
        }
        _id -= 1;
    }
    return _id;
}

那个标题非常令人困惑。我们能否有更多的细节说明? - Nate Koppenhaver
重要的修改,没错。我可能在你自己处理之前就把它从关闭中拯救了出来。希望我做得没错。 - Edward Strange
这段代码示例是由 moc 生成的,对吗? - aschepler
是的,除了我更改了对象名称。 - Edward Strange
2个回答

2
坦白说,我也从来没能搞明白这个。创建 void ** 结构的方式与此相同,只需将 int* 强制转换为 void*,然后在另一侧执行这种奇怪的转换。据我所知,使用 static_cast 不仅可以正常工作,而且更好。
你会发现,在像 Qt 这样的大型项目中有很多可疑的代码。有时候会漏过审核或者存在是因为没有人想去改变它。

1
换句话说,他们不知道更好的方法,也没有人在意去修复它。 - GManNickG
4
请注意,Qt是在我们今天所知道的“现代C ++”真正出现之前创建的,因此他们可能真的不知道更好的方法。回头重新实施框架(并且不破坏现有应用程序)以使用更少受质疑的代码成本太高(以时间和人力为代价),尤其是因为Qt代码几乎总是依赖于moc工具。 - In silico
@Insilico:不过他们每个主要版本都会破坏兼容性,所以这并不重要。 - Euri Pinhollow

1
这篇文章有点老了,但我不同意大家的共识。你不应该使用static_cast将任何类型转换为void*,你只能使用reinterpret_caststatic_cast仅适用于被认为是兼容的类型,会执行一些编译时检查(例如派生类、它们之间的数字类型)。
来自这个链接MSDN
dynamic_cast      Used for conversion of polymorphic types.
static_cast       Used for conversion of nonpolymorphic types.
const_cast        Used to remove the const, volatile, and __unaligned attributes.
reinterpret_cast  Used for simple reinterpretation of bits.

我认为你理解错了... 你可以通过简单地赋值来将任何指针隐式转换为void*。此外,问题是关于另一种情况...从void*进行转换。 - Xeo
是的,你可以这样做。但你不应该这样做。这不是为了支持遗留的C代码吗?在我看来,好的C++风格应该使用reinterpret_cast来警告用户这是一个潜在棘手的指针转换。使用static_cast会产生误导,暗示两种类型之间存在某种关系,而当其中一种类型为void*时,这总是错误的。 - J.N.
1
我不同意。C++标准明确保证了从对象指针到void*再返回_原始_指针类型的static_cast是安全的,但使用reinterpret_cast可能会产生不同的结果。 - bjhend

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接