载体如何自我清理? (或者他们?)

时间:2015-11-17 00:40:58

标签: c++ pointers memory-management vector

我正在为我的编程课制作一个模拟双向飞碟拍摄的游戏。 主Game类包含std::vector<Bullet> bullets,其中Bullet是我的类。它仅包含具体类型的成员,并覆盖基础Drawable类以绘制和更新自身。它不会重新定义任何运营商。在每一帧,bullets都会循环,每个项目符号都会被更新和绘制。

当用户按下某个键时,我将Bullet添加到bullets,如下所示:

在Game :: handleInput:

if (ui.isSpaceBar())
{
   Bullet newBullet = rifle.fire();
   addBullet(newBullet);
}

rifle.fire会像这样返回Bullet

Bullet Rifle :: fire()
{
   ... calculation of position and velocity...
   return Bullet(...position and velocity values...);
}

addBullet看起来像这样:

void addBullet(const Bullet & newBullet)
{
   bool assigned = false;
   for (int i = 0; i < bullets.size(); i++)
   {
      // If the i'th bullet is off-screen or hit something ...
      if (bullets[i].isDead())
      {
         // ... then overwrite it with the new bullet,
         // instead of using push_back, to avoid constantly
         // increasing the size of the vector
         bullets[i] = newBullet;
         assigned = true;
         break;
      }
   }

   if (!assigned)
      bullets.push_back(newBullet);
}

我的问题是关于bullets[i] = newBullet;行。在使用索引器覆盖向量中的值之前,是否需要delete任何内容?如果我理解正确,使用值代替指针(Bullet代替Bullet *return Bullet(...)代替return new Bullet(...))意味着我不必使用{ {1}},delete实例在超出范围时会自动销毁,这将在向量超出范围时进行。是对的吗?如果是这样,使用向量的索引器运算符Bullet是否使用旧值(在这种情况下,&#34;死&#34;项目符号)?如果没有,我错过了什么?我应该使用指针而不是值吗?

1 个答案:

答案 0 :(得分:2)

当您使用具体对象(例如Bullet)而不是指向对象的指针时,您不需要使用删除。

因此bullets[i] = myBullet会复制myBullet。它会将bullets[i]的旧值指定为myBullet的新值。当向量超出范围时,它将调用它的每个元素析构函数,它清理元素所拥有的任何内存。

为了在技术上正确,上述语句使用赋值运算符(operator=)来制作副本。这样做可以清除旧的bullet并将新的bullet's成员变量复制到旧的bullet's成员变量。

bullets.push_back(myBullet)类似。除了它将myBullet添加到向量的末尾。这意味着如果向量的大小为9,那么它现在将为10。

为了在技术上正确,push_back使用复制构造函数而不是赋值运算符来构造新对象(我认为),因为没有现有的旧bullet对象。

底线是给定一个正确实现的具体类(无论内部有多复杂),您可以在std::vector中使用它们的实例,而不用担心进行任何内存清理。