【问题标题】:Correct way to pass object arrays to functions?将对象数组传递给函数的正确方法?
【发布时间】:2021-09-09 18:06:58
【问题描述】:

所以最近,我一直在努力将数组传递给函数(如下所述)。我的问题是,当我传递一个数组时,只有数组的第一个元素才能正常工作(用 cout 显示)。而且,对象“Enemy”是“Obj”的子对象。

创建一系列敌人:

    const int eN = 2;
    Enemy enemyArray[eN];
    for (int i = 0; i <eN; i++) {
        enemyArray[i].creating("abc.png", Type::ENEMY);
        enemyArray[i].position = Vector2f(x, y);
        enemyArray[i].loadChasePoint();
        enemyArray[i].number = i + 100;
        enemyArray[i].updatePosition();
        x += 50; y += 50;
    }

包含这个数组的函数:

void Obj::movement(Vector2f mVector, Obj* b, int objsNumber) {
    bool collision = false;
    position.x = position.x + mVector.x;
    for (int i = 0; i < objsNumber; i++) {
        if (!(type == Type::NONE)) {
            //if (type == Type::PLAYER) { cout<<"Inside: "<< b[1].getSprite().getPosition().x << endl;} Prints "0"
            if (isColliding(b[i])) collision = true;
        }
    }
    if (collision == 1) position.x = position.x - mVector.x;
    collision = false;
    position.y = position.y + mVector.y;
    for (int i = 0; i < objsNumber; i++) {
        if (!(type == Type::NONE)) {
            
            if (isColliding(b[i])) collision = true;
        }
    }
    if (collision == 1) position.y = position.y - mVector.y;
}

调用该函数:

//cout <<"Outside: "<<enemyArray[1].getSprite().getPosition().x<<endl; Prints actuall position
playerArray[0].movement(mVector, enemyArray, eN);

【问题讨论】:

  • 我认为这段代码中关于数组的传递和访问它的元素没有任何问题。那么实际问题是什么?请更具体。
  • 附注:if (collision == 1) 应该是 if (collision == true) 或只是 if (collision)。而if (!(type == Type::NONE)) 应该是if (type != Type::NONE)。另外,不要在每次循环迭代时检查type,因为它不会改变值,您应该完全在循环之外检查它,例如:if (type != Type::NONE)) { for (int i = 0; i &lt; objsNumber; i++) { if (isColliding(b[i])) collision = true; } } 运行相同的碰撞循环两次有什么意义呢?你不能把它们合并成一个循环,同时检查position.xposition.y吗?
  • 您需要另一个级别的间接。即使假设EnemyObj 的子类,Enemy 的数组在内存中的布局与Obj 的数组不同。在数组中找到第二个Obj 所需的偏移量与在数组中找到第二个Enemy 所需的偏移量不同。
  • 我的意思是你是对的,但是应该在每次循环迭代时检查它,就像这样:for (int i = 0; i &lt; objsNumber; i++) { if (b[i].type != Type::NONE)) { if (isColliding(b[i])) collision = true; } } ,但这是我的错。正如我所写的,问题在于关于敌人精灵的信息没有正确传递到函数中。我可以提供整个代码,但它有点大(300 行)。另一件可能会有所帮助的事情是我使用 SFML 2.5.1 和 VS 2019。
  • @MilesBudnek 我想我明白你的意思。但是,您能否解释一下如何做到这一点,或者只是提供某种教程的链接?

标签: c++ arrays function object


【解决方案1】:

问题是,您将Enemy 类型的数组传递给需要Obj 类型数组的函数。这仅在您传递单个对象并且Enemy 继承自Obj 时才有效。这不适用于数组:
sizeof(Obj) 是一些 X。所以访问obj[1] 会期望第二个对象从地址adressof(b)+X 开始。

但是由于您的对象数组是 Enemy 类型,它具有不同的大小(很可能是 X+Y),因此此时指针算术失败,因为第二个对象的实际地址是 adressof(b)+x+y

解决这个问题的一些变体:

  • 使b 成为您的movement - 用作模板论证
  • b 参数更改为 Obj*-Array 并在调用函数之前从敌人列表中创建指针数组

我更喜欢第一个变体。如果您要重构 - 我建议摆脱普通的指针和数组。改用 std 容器并使用它们的迭代器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 2012-01-20
    • 2012-10-11
    • 2020-12-22
    相关资源
    最近更新 更多