【发布时间】:2024-01-18 16:45:01
【问题描述】:
以下是 PhysX 示例中的一些代码:
std::vector<PxRigidActor*> actors(nbActors);
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC,
reinterpret_cast<PxActor**>(&actors[0]), nbActors);
然后在getActors 函数的代码中,他们像这样使用它:
PxU32 NpScene::getActors(PxActorTypeFlags types, PxActor** buffer, PxU32 bufferSize, PxU32 startIndex=0) const
{
...
if ((types & PxActorTypeFlag::eRIGID_STATIC ) && mRigidActors[i]->is<PxRigidStatic>())
{
if (virtualIndex >= startIndex)
buffer[writeCount++] = mRigidActors[i];
virtualIndex++;
}
else if ((types & PxActorTypeFlag::eRIGID_DYNAMIC) && mRigidActors[i]->is<PxRigidDynamic>())
{
if (virtualIndex >= startIndex)
buffer[writeCount++] = mRigidActors[i];
virtualIndex++;
}
...
}
mRigidActors 定义为Ps::Array<PxRigidActor*>
继承图如下:
所以,我的问题是:
-
听说父类的指针可以指向子类的实例。那么,为什么我们需要任何铸造呢?我试过了,但是不强制转换是不行的。
-
在这里使用 reinterpret_cast 是否安全? (我想是的,因为它只是指针转换)
-
有没有更好的解决方案?
【问题讨论】:
-
PxRigidActor和PxActor有什么关系? -
这基本上是将
actors.data()重新解释为PxActors**而不是PxRigidActor**。从这个名字听起来,一个是从另一个派生而来的。看起来reinterpret_cast可能是在这里使用的错误类型,当您看到reinterpret_cast时通常会出现这种情况。编辑:使用&actors[0]而不是actors.data(),reinterpret_cast和if/else if的链似乎正在检查每种具体类型对我来说都是危险信号,向我表明这代码不应该作为一个很好的例子。 -
我相信
reinterpret_cast被用来代替static_cast因为你不能static_cast双指针,因为它们永远不会通过继承相关联。使用显式转换是因为您不能隐式执行reinterpret_cast。 -
@vandench 无论 ABI 是什么,任何编译器都可能在优化过程中破坏这一点。 UB 在静态分析期间可能很明显(它似乎不依赖于运行时信息),因此编译器可以发现它。并且允许编译器假设UB没有发生,因此它可以在控制永远不会到达函数调用的假设下优化函数。例如,如果函数调用在
if后面,编译器可以假定if的条件始终为false。它现在可能有效,但随时可能中断。 -
@vandench 你不能通过测试来反驳 UB。语言规则不允许这样做,生成的二进制文件与它无关。 UB 是一个抽象概念,将应用于抽象 C++ 机器。严格别名的目的主要是让编译器通过缩小aliasing problem的范围来进行更好的优化。我想垃圾回收也有必要,但是严格别名的存在时间比垃圾回收的允许时间要长得多。
标签: c++ inheritance casting reinterpret-cast