快速实例化对象 - 好还是坏?

时间:2014-03-17 16:49:09

标签: c++ oop

注意: 虽然这个问题与游戏没有直接关系,但我已经围绕游戏开发模拟了上下文,以便更好地直观地展示这个问题的场景。相关的。

tl; dr:是否正在快速创建同一类内存的对象内存密集,效率低下,还是常见的做法?

说我们有一个"子弹" class - 每次玩家“射击”时都会创建所述类的实例。 - 每秒1至10次。碰撞时(显然)可能会破坏这些实例。

这会是一个糟糕的主意吗?一般OOP在这里是否可以(即:class Bullet { short x; short y; }等)或者有更好的方法吗? newdelete是首选吗?

任何输入都非常感激。谢谢!

4 个答案:

答案 0 :(得分:2)

不要只是不断创建和删除对象。相反,另一种方法是拥有一个可以重用的常量,可调整大小的数组或对象实例列表。例如,创建一个包含100个项目符号的数组,它们不必全部绘制,有boolean表示它们是否“活动”。

然后,当您需要新子弹时,“激活”非活动子弹并将其位置设置在您需要的位置。然后,只要屏幕不亮,就可以再次将其标记为非活动状态,而不必将其删除。

如果您需要更多超过100个项目符号,只需展开数组。

请阅读本文以了解更多信息:Object Pool。它还有其他几个与游戏模式相关的主题。

答案 1 :(得分:2)

对于像memory-poolsFree-Lists这样的技术来说,这听起来很不错。两者的想法是你有预先分配了一定数量元素的记忆。您可以覆盖类的new运算符以使用池/列表,或使用placement new在检索到的地址中实例化您的类。

优点:

  • 没有内存碎片
  • 很快

缺点:

  • 您必须事先了解最大元素数

答案 2 :(得分:2)

分配对象时发生的最不重要的是函数调用(它的构造函数)。如果这种分配是动态的,那么内存管理的成本也会因碎片而在某些时候变得非常激烈。

每秒调用一些函数10次真的很糟糕吗?不会。每秒动态创建和销毁许多小物件会不好?有可能。你应该这样做吗?绝对不是。

即使没有“感觉到”性能损失,在最佳解决方案立即可用的情况下,也不可能有一个次优的解决方案。

因此,代替动态添加和删除的std::list个对象,您可以简单地拥有std::vector个子弹,其中添加项目符号意味着附加到向量(在它之后达到足够大的大小,不应再需要任何内存分配了)删除意味着用最后一个元素交换被删除的元素并从向量中弹出它(实际上只是减少了向量大小变量)。

答案 3 :(得分:1)

认为在每个实例化中,堆中都有一个位置需要分配内存并创建新实例。这可能会影响性能。尝试使用集合并使用您想要的子弹数创建该集合的实例。