我最近涉足图形编程,并且注意到许多图形引擎(即Ogre)和许多编码器都更喜欢动态地初始化类实例。这是Ogre Basic Tutorial 1的示例

//...

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");

//...

然后将ogreHeadheadNode数据成员和方法称为ogreHead->blabla

为什么要搞乱对象指针而不是普通对象?

顺便说一句,我还在某处读到堆内存分配比堆栈内存分配慢得多。

最佳答案

堆分配不可避免地要比栈分配慢得多。更多关于“慢多少?”后来。但是,在许多情况下,出于以下几个原因,选择是“为您量身定制”:

  • 堆栈是有限的。而且,如果用完了,应用程序几乎总是会终止-没有真正好的恢复,即使打印一条错误消息说“我用完了堆栈”也可能很难...
  • 当您离开进行分配的函数时,堆栈分配“消失”。
  • 变量的定义更加明确并且易于处理。 C++不能很好地处理“可变长度数组”,并且肯定不能保证在所有编译器中都能正常工作。

  • 堆比堆栈慢多少?

    我们将稍等一下。

    对于给定的分配,堆栈分配只是一个减法运算[1],其中最少newmalloc将是一个函数调用,甚至最简单的分配器也可能是几十条指令,在复杂情况下,数千条[因为内存必须从操作系统中获取,并清除其先前的内容]。因此,从10倍到“无限”变慢的任何事物,都可以接受或接受。确切的数字将取决于代码运行的确切系统,分配的大小以及通常是“对分配器的先前调用”(例如,一长串的“释放”分配可能会使分配新对象的速度变慢,因为很合适)必须搜索)。当然,除非您使用堆管理的“鸵鸟”方法,否则还需要释放对象并应对“内存不足”,这会增加代码/时间的执行量和代码复杂性。

    但是,使用一些相当聪明的编程,这几乎可以被隐藏起来-例如,在对象的整个生命周期中分配长时间保持分配状态的内容将“无须担心”。从堆中为3D游戏中的每个像素或每个三角形分配对象显然不是一个好主意。但是,如果对象的生命周期是很多帧甚至整个游戏,那么分配和释放它的时间将几乎没有。

    同样,不要对10000个对象进行单独分配,而是对10000个对象进行分配。对象池就是这样一种概念。

    此外,分配时间通常不是花费时间的地方。例如,从磁盘上的文件读取三角列表将比为同一三角列表分配空间要花费更长的时间-即使您分配了每个三角列表!

    对我来说,规则是:
  • 它是否非常适合堆栈?通常情况下,几千字节就可以了,很多千字节不是那么好,而兆字节绝对不行。
  • 是否知道数量(例如,对象数组),以及您可以将其放入堆栈的最大值?
  • 您知道对象是什么吗?换句话说,可能需要在堆上分配抽象/多态类。
  • 它的生存期与它的作用域相同吗?如果不是,请使用堆(或将堆向下放置,然后将其向上传递)。

  • [1]如果堆栈是“朝着高地址增长”的话,或者添加-我不知 Prop 有这种架构的机器,但是这是可以想象的,而且我认为已经完成了。对于堆栈的增长方式,或者有关运行时堆栈如何工作的任何其他事项,C毫无疑问。

    09-06 07:30