передача параметров — изменение значения переменной-члена в функции

Я занимаюсь определением коллизий и обработкой для игры 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() при изменении переменной.

Будем благодарны за любые комментарии, которые вы можете сделать, чтобы помочь с этим, спасибо!

1

Решение

Вы передаете параметры по значению. Это означает, что функции получают свои собственные копии. Похоже, вам нужно передать ссылки:

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

Обратите внимание, что здесь я отметил второй параметр как constпотому что вы не измените его в функции. Нужно ли передавать значение или ссылку в этом случае — это только вопрос оптимизации. Только первый параметр должен быть (неконстантной) ссылкой.

5

Другие решения

Это не работает, потому что вы передали свой объект по значению:

void HandleCollision(sprite obj1, sprite obj2);

Вместо этого вы должны передать их по ссылке:

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

Если вы определяете свою функцию так, как вы (передавая по значению), два аргумента будут скопированы, и функция будет использовать копии.
Таким образом, даже если вы измените их члены, эти копии будут уничтожены, как только функция вернется, и за пределами вас ваши исходные спрайты останутся неизмененными.

С другой стороны, если вы определите свою функцию для приема ссылок на объекты, копии не будут сделаны, и вы сможете изменить их.

Также обратите внимание, что при передаче по ссылке тот факт, что эти объекты не копируются в стек, означает меньшее количество операций с памятью и лучшую производительность.

В заключение, ваш CheckCollision Функция работает, потому что вы не изменяете спрайты, а только должны читать с них, но вы действительно должны также перейти по ссылке. На самом деле, вы всегда должны передавать по ссылке при передаче объектов в качестве аргументов, потому что это быстрее. Если вам не нужно изменять объект, вы должны передать их как постоянную ссылку:

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

Вы можете передать параметр по ссылке или с помощью указателей. Если есть вероятность, что вы можете передать объект, который не имеет значения, тогда указатели будут моим методом перехода к методу. Все зависит от того, что вы хотите сделать с ним, хотя.

0
По вопросам рекламы [email protected]