向下投射指针

Downcasting pointers

本文关键字:指针      更新时间:2023-10-16

基本上,我有两个类,Spatial和Node,继承自IEntity;IEntity是一个抽象类(接口)。我将Entity对象指针存储在SceneGraph类的std::vector中,如std::vector<IEntity*>。因此,为了区分空间和节点,我首先想到了进行

if(!dynamic_cast<Node*>(myEntity)) // equals nullptr, cast failed
{
  BOOST_LOG_TRIVIAL(info) << "It is a node !";
}

但这段代码将用于高性能引擎,我负担不起一秒钟内成千上万的动态强制转换调用;那么,你建议如何区分空间指针和节点,以便在没有任何错误的情况下(以最快的方式)向下转换?PS。我知道不建议将指针存储在stl容器中,但这是解决imo的最佳方法。

首先,在这种情况下必须向下转换是糟糕设计打破Liskov原则的明显迹象。要在OOP域中修复它,您应该为每个IEntity对象调用一个特定的虚拟函数,而不是下转换,然后它将对NodeSpatial执行不同的操作。

其次,如果您的目标是性能,那么您应该在性能关键代码中放弃OOP。即不调用虚拟函数。您还应该尽可能多地利用内存缓存,因为对非缓存数据的内存访问通常是大多数性能关键代码的瓶颈。如何做到这一点?谷歌的"数据驱动设计"或"面向数据的编程"。这通常使用一种称为"实体组件系统"的东西来实现,通常在计算机游戏中。在您的情况下,您可能需要将NodesSpatials在分离的向量中保持分离,而不是通过引用或指向IEntity,而是通过值(使用vector<Node>vector<Spatial>而不是vector<IEntity*>),然后线性地或按可预测/规则的顺序遍历它(以利于预取数据)。这将给你带来你所能达到的最高速度。也许只有在那之后,你才应该开始一些算法微调。。。这是典型的情况,所以我认为这也是您的情况。

Btw。除了性能(在您的情况下)之外,在STL容器中存储指针并没有错。还是有?

更新:正如您在下面提到的,由于一些算法原因,您可能需要将对象保持在树结构中。在这种情况下,我关于按值将对象保存在容器中的建议可能没有那么有用或实现起来那么简单。无论如何,在任何情况下,你都必须首先对我们的代码进行评测,然后尝试优化和篡改缓存等。然而,我关于需要向下转换的糟糕设计的第一条注释仍然有效。:)