如何通过C 中的类对象循环

How to loop through class objects in C++

本文关键字:对象 循环 何通过      更新时间:2023-10-16

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

目前我通过编写Enemy(class)并给出object + number名称来创建我的敌人,然后我只给出一些输入,看起来像:

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

然后我有一个战斗时间,我在循环时运行一个可怕的事情:

while (object1.getHp() > 0)

运行我的战斗代码。

因此,现在我只需要一个战斗功能来运行所有不同的敌人,我已经尝试了很多事情,但似乎没有任何作用。对我该怎么办?

听起来很愚蠢,但我真的无法猜测任何事情要做,已经损失了很多小时寻找解决方案。

首先需要的是一个容器,能够将Enemy实例或指针保留给它们。大多数容器是模板类,必须键入。其中之一是向量(一个连续的"列表"),可以在您的情况下以

创建
  • std::vector<Enemy>:持有完整对象的"列表"
  • std::vector<Enemy*>:一个"列表"将指针固定到您的对象

一个示例,如果您从对象中获取参考:

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

如果您不熟悉指针,即使起初可能有点不透明!

,也可以在这里查看!

循环

循环范围将使您轻松地在容器上迭代

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

auto将从容器中推导类型,doStuff将对列表中的每个敌人顺序执行。如果您的容器包含实例而不是指针*,则需要使用对象的参考&,然后使用for ( auto& enemy : enemies )。这将确保您的对象被修改到位,而不会复制,否则,您的更改不会反映在容器中。

内存管理

如其他答案中所述,当您准备好进入一个新的水平时,您可以看一下智能指针。因为C 代码是未管理的,并且没有现成的内存管理,因此 you 负责delete对任何new ED对象。智能指针将帮助您更安全地管理数据的寿命。在当今大多数情况下,原始指针(没有任何明智的指针来保护它们)被认为是不良习惯。

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

您可以使用std :: vector这样的对象进行分组:

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

,然后您可以使用C 11的范围循环进行所有对象:

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

您也可以为其他用例探索std :: for_each。


如果您正在寻找带有指针的解决方案,例如std::vector<Enemy*>然后,您应该首先查看智能指针(std :: simel_ptr/std :: shared_ptr以及std :: make_unique/std :: make_shared),以执行在堆上分配的对象。

请在下面找到解决问题的粗略说明。

  • 将所有对象存储在数组或高级结构中。
  • 设置一个标志来指示至少有一个活着的敌人
  • 只要标志保持真实
    • 将标志设置为false
    • 对于数组中的每个对象,
    • 检查健康点是否超过零
      • 然后执行您的动作
      • 将公平设置为true

仅此而已。

定义敌人的容器,最好是 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
}