Свойства класса С++ не обновляются должным образом

У меня есть пользовательский класс galaxy, у которого есть настраиваемое свойство pos. pos является экземпляром другого пользовательского класса Vector3D. Vector3D имеет свойства x, y, z. Арифметические операции для Vector3D — это базовая векторная математика, соответствующие ниже:

Vector3D Vector3D::operator+(const Vector3D& vec) {
    return Vector3D(x + vec.x, y + vec.y, z + vec.z);
}

Vector3D &Vector3D::operator+=(const Vector3D& vec) {
    x += vec.x;
    y += vec.y;
    z += vec.z;
    return *this;
}

Vector3D Vector3D::operator*(double val) {
    return Vector3D(x * val, y * val, z * val);
}

galaxy.cpp имеет несколько методов ниже:

void galaxy::updatePos(double dt) {
    pos += vel * dt;
}

void galaxy::updateVel(Vector3D accel, double dt) {
    vel += accel * dt;
}

void galaxy::updateStateVectors(Vector3D accel, double dt) {
    updateVel(accel, dt);
    updatePos(dt);
}

main.cpp вызывает метод updateStateVectors следующим образом:

// within some while() loop

for (auto g : galaxies) {
    Vector3D accel = Vector3D();
    for (auto g2 : galaxies) {
        if (g != g2) {
            accel += g.getGravityAccelBy(g2);
        }
    }
    g.updateStateVectors(accel, dt);
}

(галактики это std::vector<galaxy>)

Проблема в том, что изменения, внесенные в g.pos (или g.vel) в этом цикле for, похоже, не сохраняются. На каждой итерации цикла while я вижу, что g.pos возвращается к своему исходному значению, несмотря на изменения, которые он ранее претерпел в цикле for. Что мне не хватает?

Это может оказаться очень глупой ошибкой, но я в основном программирую на Python и потратил на это больше времени, чем хотел бы признать.

Вы должны использовать ссылку. Измените auto g на auto& g, то же самое для g2

bielu000 02.04.2022 13:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
40
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

auto возвращает копию объекта, поэтому исходным является скопировано, не измененный. Затем вы изменяете копировать исходного объекта. Использование & заставит вас сослаться на оригинальный, чтобы вы могли его изменить.

for (auto & g : galaxies) {
    Vector3D accel = Vector3D();
    for (auto & g2 : galaxies) {
        if (g != g2) {
            accel += g.getGravityAccelBy(g2);
        }
    }
    g.updateStateVectors(accel, dt);
}

Цикл for (auto g : galaxies) { создает копию элементов из galaxies в g. Поэтому изменения в g не сохраняются в galaxies.

Вместо этого вы должны использовать ссылку на такие элементы, как for (auto& g : galaxies) {.


отказ от ответственности:

я гуглил

  • site:stackoverflow.com [c++] range for not updated reference
  • site:stackoverflow.com [c++] range-based-for not updated reference
  • site:stackoverflow.com [c++] range-based-for not updated
  • site:stackoverflow.com [c++] range-based change value

но не смог найти дубликат.

Попробуйте использовать этот способ, чтобы увидеть, работает ли он.

for (auto g& : galaxies) {
    Vector3D accel = Vector3D();
    for (auto g2 : galaxies) {
        if (g != g2) {
            accel += g.getGravityAccelBy(g2);
        }
    }
    g.updateStateVectors(accel, dt);
}

поскольку в for (auto g: galaxies) создан временный объект (например: temp_g), все изменения применяются к временному объекту.

Другие вопросы по теме