parameter passing-更改函数-C++中成员变量的值

parameter passing - Change value of member variable within function - C++

本文关键字:成员 变量 -C++ passing- 函数 parameter      更新时间:2023-10-16

我正在为我正在编写的GBA游戏进行一些碰撞检测和处理,在将处理部分放入函数时遇到了问题。我正在尝试更改成员变量(在本例中为Player.global_x)的值,但是将对象传递到函数中不允许这样做。相关代码如下:

main.cpp

bool CheckCollision(sprite obj1, sprite obj2){
    int obj1_top = obj1.global_y;
    int obj1_bottom = obj1.global_y + (obj1.height-1);
    int obj1_left = obj1.global_x;
    int obj1_right = obj1.global_x + (obj1.width-1);
    int obj2_top = obj2.global_y;
    int obj2_bottom = obj2.global_y + (obj2.height-1);
    int obj2_left = obj2.global_x;
    int obj2_right = obj2.global_x + (obj2.width-1);
    if(obj1_right < obj2_left){     // if obj1 is left of obj2
        return false;
    }
    if(obj1_left > obj2_right){     // if obj1 is right of obj2
        return false;
    }
    if(obj1_bottom < obj2_top){     // if obj1 is above obj2
        return false;
    }
    if(obj1_top > obj2_bottom){     // if obj1 is below obj2
        return false;
    }
    return true;
}
void HandleCollision(sprite obj1, sprite obj2){
    if(obj1.direction == RIGHT){
        Player.global_x -= (obj1.global_x + obj1.width) - obj2.global_x;    // This works but is not modular
        obj1.global_x -= (obj1.global_x + obj1.width) - obj2.global_x;      // This does not work
    }
}
void CheckAllPossibleCollisions(){
    bool collision = false;
    for(int i=0; i<(WallsVector.size()); i++){
        collision = CheckCollision(Player, WallsVector.at(i));
        if(collision==true){
            // This piece of code works, but would incur repetition of code for each different type of game object
            /*if(Player.direction == RIGHT){
                Player.global_x -= ((Player.global_x+Player.width) - WallsVector.at(i).global_x);
            }*/
            HandleCollision(Player, WallsVector.at(i));
        }
    }
}

CheckCollision()函数在传入对象时工作良好,但在HandleCollision()中更改变量时不起作用。

如果您能对此提供任何意见,我们将不胜感激,谢谢!

您正在按值传递参数。这意味着函数有自己的副本。看起来你需要传递参考:

void HandleCollision(sprite& obj1, const sprite& obj2)

请注意,在这里,我将第二个参数标记为const,因为您不会在函数中修改它。在这种情况下,是否应该传递值或引用只是一个优化问题。只有第一个参数需要是(非常数)引用。

这不起作用,因为您通过值传递了对象:

void HandleCollision(sprite obj1, sprite obj2);

相反,您应该通过引用传递它们:

void HandleCollision(sprite& obj1, sprite& obj2);

如果像以前那样定义函数(传递值),那么两个参数将被复制,函数将使用这些副本
因此,即使您更改了它们的成员,只要函数返回,这些副本也会被销毁,在外部,您将无法修改原始精灵。

另一方面,如果您将函数定义为接受对对象的引用,则不会生成任何副本,并且您可以修改它们。

还要注意,当通过引用传递时,这些对象没有复制到堆栈上,这意味着更少的内存操作和更好的性能。

最后要注意的是,CheckCollision函数之所以有效,是因为您不需要更改精灵,只需要从中读取,但您也应该在其中通过引用传递。事实上,在将对象作为参数传递时,您应该始终通过引用传递,因为这样会更快。如果你不需要修改对象,你应该把它们作为一个常量引用来传递:

bool CheckCollision(const sprite& obj1, const sprite& obj2);

您可以通过引用或使用指针传递参数。如果您有可能传递一个没有值的对象,那么指针实际上就是我的首选方法。不过,这完全取决于你想用它做什么。