另一个问题:通过引用传递参数

Another issue: Passing argument by reference

本文关键字:参数 引用 问题 另一个      更新时间:2023-10-16

所以我认为我有通过引用传递下来的想法,但似乎我仍然在努力解决这个问题。

这是我的问题,我一直在调试我的游戏一段时间,我让我的代码的敌人部分保持不变。说来话长,我认为我的炮弹对敌人造成了伤害,我把敌人的血量调得很高,所以我认为他们造成了伤害,但因为血量高,而不是杀死敌人。直到现在我才意识到他们没有造成任何损害,代码是错误的:/

这里是i开始的地方:

void Towers::Update(std::vector<Enemies>& enemies, SDLib& lib, Map cMap)   

这里我通过引用将敌人传递给我的更新函数。然后我去看看是否有敌人在塔的范围内;

for (int numOfEnemies = 0; numOfEnemies < lib.numberOfEnemies; numOfEnemies++)
{
    float y =  pow(enemies[numOfEnemies].position.y - position.y, 2);
    float x = pow(enemies[numOfEnemies].position.x - position.x, 2);
    if (sqrt(y + x) < range && enemies[numOfEnemies].alive)
    {
        cEnemy = enemies[numOfEnemies];
        acquiredTarget = true;
        break;
    }
}

敌人(currentenenemy),然后持有在范围内的敌人。在此之后,我然后创建发射,这里是我认为我搞砸了;

bullet = Projectile((float)position.x, (float)position.y - 8, 8, 8, 0, 0, damage, 1, speed, cEnemy);

函数参数为:

Projectile::Projectile(float x, float y, int w, int h, int sX, int sY, int dmg, int type, float mxSpeed, Enemies bulletTarget)
{
     //....other values set. 
     target = bulletTarget;
}

(目标如下)

Enemies target;
这里的想法是目标应该保存我通过函数设置的初始敌人的引用…但它并没有像我想的那样工作。我不太确定,但我猜这里可能需要某种形式的指针。这似乎是我发现最难掌握的概念,并且已经做了一段时间了。

感谢任何帮助!

您正在复制Enemies对象:

  • On cEnemy = enemies[numOfEnemies];
  • 当传递一个值给Projectile构造器时,因为它接受一个Enemies的值。
  • On target = bulletTarget;

要解决所有这些问题,您需要考虑哪些代码"拥有"Enemies对象,并确保它存在足够长的时间,以便所有试图使用它的代码。如果有这样的地方,所有其他地方都应该使用引用或指针。如果没有,也许你可以把责任交给shared_ptr<Enemies>

我们这里缺少了一些信息,但是有一行可能导致这一点:

cEnemy = enemies[numOfEnemies];

我不知道cEnemy的类型是什么,但似乎你是从列表中复制你的敌人对象,而不是仅仅引用它。

你知道你可以这样创建一个本地引用吗:

Enemies& cEnemy = enemies[numOfEnemis];

也就是说,cEnemy将指向列表中的敌人,而不是副本。

如果你这样做,要小心,因为cEnemy只是一个引用,如果你修改你的列表,这个引用可能会无声地丢失。

你确定你的Enemies类应该是可复制的吗?如果不应该,将其修改为不可复制,将使编译器成为查找此类"错误"的最好朋友。

您将Enemies参数按值传递给Projectile构造函数,然后也按值存储它。

如果您希望targetcEnemy的引用,那么两者都需要是引用。还要注意,引用成员必须在构造函数的初始化列表中初始化,因为它们不能像你的代码那样在主体中重新赋值。

class Projectile 
{
public:
    Projectile(/*lots of args*/, Enemies & target) :
        target(target)
    {}
private:
    Enemies & target;
};

你的问题缺少一些关于敌人类型和你如何使用目标的信息,所以我猜cEnemy被定义为Enemies,你需要target的引用来更新正确的对象。在这种情况下,您的问题如下:

  1. cEnemy = enemies[numOfEnemies];复制而不是引用
  2. 由于bulletTargetEnemies类型的bullet = Projectile((float)position.x, (float)position.y - 8, 8, 8, 0, 0, damage, 1, speed, cEnemy);进行复制
  3. 由于targetEnemies类型,target = bulletTarget;复制

引用通常只在构造时获取地址,以后的赋值会生成副本。因此,要解决第一项,您需要将cEnemy设置为指针:

Enemies* cEnemy;
//some code
cEnemy = &enemies[numOfEnemies];
//some more code
第二项可以通过将构造函数定义为 来解决
Projectile::Projectile(float x, float y, int w, int h, int sX, int sY, int dmg, int type, float mxSpeed, Enemies& bulletTarget)

第三项可以通过将target定义为引用并在初始化列表中初始化它来解决(最后一部分很重要),使其

Enemies& target;
Projectile::Projectile(float x, float y, int w, int h, int sX, int sY, int dmg, int type, float mxSpeed, Enemies& bulletTarget):target(bulletTarget)
{}

由于对引用的赋值是一个复制操作(只有引用的构造需要地址),如果你不能在初始化列表中初始化target,你需要使它成为一个指针:

Enemies* target;
Projectile::Projectile(float x, float y, int w, int h, int sX, int sY, int dmg, int type, float mxSpeed, Enemies& bulletTarget)
{  
   target = &bulletTarget;
}

"