如何在C ++中遍历类对象

时间:2019-03-12 04:54:26

标签: c++

我的问题是,只有1个功能,如何才能与所有敌人战斗?

此刻,我通过编写Enemy(类)并给其命名为object + number来创建敌人,然后我给出一些输入,如下所示:

Enemy object1(1, 20, '/', "AQUA", 1);
Enemy object2(5, 40, '/', "YELLOW", 2);
Enemy object3(10, 60, '/', "WHITE", 3);

然后我有一个Combat运行时,并且运行了一个糟糕的while循环:

while (object1.getHp() > 0)

运行我的战斗代码。

所以现在我只需要一个战斗功能即可对付所有不同的敌人,我已经尝试了很多事情,但似乎没有任何效果。关于我该怎么办?

听起来很笨,但我真的无法猜测如何解决,已经浪费了很多时间寻找解决方案。

4 个答案:

答案 0 :(得分:4)

首先需要一个container,它能够容纳您的Enemy实例或指向它们的指针。大多数容器是模板化的类,必须键入。其中之一是vector(一个连续的“列表”),可以根据您的情况创建为

  • std::vector<Enemy>:保存完整对象的“列表”
  • std::vector<Enemy*>:包含指向您对象的指针的“列表”

从对象中获取引用的示例:

std::vector<Enemy*> enemies;
enemies.push_back(&object1);
enemies.push_back(&object2);
enemies.push_back(&object3);

如果您不熟悉指针,则可以看起来here,尽管起初可能有点不透明!

循环

一个for循环范围可以让您轻松地遍历容器

for ( auto enemy : enemies ) {
    enemy->doStuff();
}

auto将从容器中推断出类型,doStuff将针对列表中的每个敌人依次执行。如果您的容器包含实例而不是指针*,则将需要获取对象的引用&,并使用for ( auto& enemy : enemies )。这将确保您的对象被修改就位,并且不会被复制,否则,您的更改将不会反映在容器中。

内存管理

如其他答案所述,当您准备好进入下一个级别时,可以看看smart pointers。因为C ++代码是unmanaged,并且没有现成的内存管理,所以负责delete编写任何new ed对象。智能指针将帮助您更安全地管理数据的寿命。如今,在大多数情况下,原始指针(没有任何智能指针可以保护它们)是不受欢迎的。

但是,您的Enemy实例是在堆栈上创建的,因此它们将在其作用域的末尾(函数{},...)被自动销毁。这也意味着,如果您在此范围之外使用任何指针*或对其的引用,则您的对象已被破坏,并且您将遇到内存异常或未定义的行为,即不要这样做!

答案 1 :(得分:2)

您可以使用std::vector对对象进行分组,如下所示:

std::vector<Enemy> vEnemies
{
    { 1,  20, '/', "AQUA",   1 },
    { 5,  40, '/', "YELLOW", 2 },
    { 10, 60, '/', "WHITE",  3 }
};

然后,您可以对所有对象使用C ++ 11的range-for循环:

for ( auto& e : vEnemies )
{
    e.doSomething();
}

您还可以在其他用例中探索std::for_each


如果您正在寻找带有指针的解决方案,例如std::vector<Enemy*>,那么您应该首先查看智能指针(std::unique_ptr / std::shared_ptrstd::make_unique / std::make_shared)以对对象实施RAII分配在堆/免费存储上。

答案 2 :(得分:1)

请找到以下粗略说明来解决您的问题。

  • 将所有对象存储在数组或矢量等高级结构中。
  • 设置一个标志以指示是否至少有一个活着的敌人
  • 只要标志为真,就运行while循环
    • 将标志设置为false
    • 对于数组中的每个对象,
    • 检查健康点是否大于零
      • 然后执行您的操作
      • 设置为true

仅此而已。

答案 3 :(得分:1)

最好定义一个std::vector<Enemy>敌人的容器并遍历该容器中的所有对象。

std::vector<Enemy> enemies;
// Now construct your enemies in the vector.
enemies.emplace_back(1, 20, '/', "AQUA", 1);
enemies.emplace_back(1, 20, '/', "YELLOW", 2);
.
.
// Now loop through.
for (auto & enemy: enemies) {
  enemy.Combat(); // Whatever you want
}