You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中指针/引用传递的结构体对象无法被函数修改的问题

函数无法修改以指针(或引用)传递的结构体对象

编辑:代码现在可运行

我尝试更新结构体中对象的位置,经测试Rule函数能执行,函数内的局部变量也按预期变化,但Object结构体对象的成员变量并未改变。以下是cpp文件中的相关代码:

struct Object
{
float x;
float y;
float vx;
float vy;
glm::vec4 v_Color;
unsigned int id;

  Object(float _x, float _y,
    float _vx, float _vy,
    glm::vec4 _v_Color, unsigned int _id)
    {
      x = _x;
      y = _y;
      vx = _vx;
      vy = _vy;
      v_Color = _v_Color;
      id = _id;
    }
}
std::vector<Object> red;
std::vector<Object> green;
std::vector<Object> blue;
std::vector<Object> yellow;
void Rule(std::vector<Object>* group1, std::vector<Object>* group2, float G)
{
    float g = G;
    for (int i = 0; i < group1->size(); i++) {
        Object p1 = (*group1)[i];
        float fx = 0;
        float fy = 0;
        for (int j = 0; j < group2->size(); j++) {
            Object p2 = (*group2)[j];
            float dx = p1.position.x - p2.position.x;
            float dy = p1.position.y - p2.position.y;
            float r = std::sqrt(dx * dx + dy * dy);
            if (r < 80 && r > 0) {
                fx += (dx / r);
                fy += (dy / r);
            }
        }

        p1.velocity.x = (p1.velocity.x + fx) * 0.5;
        p1.velocity.y = (p1.velocity.y + fx) * 0.5;
        p1.position.x += p1.velocity.x;
        p1.position.y += p1.velocity.y;
        if ((p1.position.x >= 800) || (p1.position.x <= 0)) { p1.velocity.x *= -1; }
        if ((p1.position.y >= 700) || (p1.position.y <= 0)) { p1.velocity.y *= -1; }
        std::cout << "Calculated velocity: " << fx << ", " << fy << std::endl; // these numbers will change
        (*group1)[i] = p1;
        std::cout << "ID: " << p1.id << ", " << "Velocity " << p1.velocity.x << ", " << p1.velocity.y << "Position: " << p1.position.x << ", " << p1.position.y << std::endl; // you will see these values do not change
    }
}

std::vector<Object> CreateObjects(unsigned int number, glm::vec4 color)
{
    
    std::vector<Object> group;
    for (int i = 0; i < 10; i++) {
        float x = rand() % 750 + 50;
        float y = rand() % 550 + 50;
        Object o(x, y, 0, 0, color, objects.size());
        group.push_back(o);
        objects.push_back(o);
    }

    return group;
}

void main()
{
    yellow = CreateObjects(10, glm::vec4(1.0f, 1.0f, 0.0f, 1.0f));
    blue   = CreateObjects(10, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f));
    green = CreateObjects(10, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
    red = CreateObjects(10, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
    Rule(&green, &green, -0.32);
    Rule(&green, &red, -0.17);
    Rule(&green, &yellow, 0.34);
    Rule(&red, &red, -0.1);
    Rule(&red, &green, -0.34);
    Rule(&yellow, &yellow, 0.15);
    Rule(&yellow, &green, -0.2);
    Rule(&blue, &green, -0.2);

}

编辑:代码现在应该可运行


问题根源及修复方案

1. 结构体成员名称不匹配

你定义的Object结构体成员是x/y(位置)、vx/vy(速度),但Rule函数里错误使用了position.x、velocity.x这类不存在的成员,这不仅会导致编译错误,更无法修改正确的变量,需要统一成员名称。

2. 拷贝对象导致修改无效

Object p1 = (*group1)[i];会创建原对象的局部拷贝,你修改的只是这个拷贝,虽然最后做了(*group1)[i] = p1;赋值,但用引用可以直接操作原对象,更高效且避免出错:

Object& p1 = (*group1)[i]; // 使用引用直接绑定vector中的原对象

3. 未定义的objects变量

CreateObjects函数里用到了objects.size(),但代码中没有声明std::vector<Object> objects;,需要补充全局定义。

4. 速度计算笔误

p1.velocity.y = (p1.velocity.y + fx) * 0.5;这里应该加fy而非fx,否则y方向速度计算错误,修正后对应结构体成员为:

p1.vy = (p1.vy + fy) * 0.5;

修正后的完整代码

#include <vector>
#include <cmath>
#include <iostream>
#include <glm/glm.hpp>

struct Object
{
    float x;
    float y;
    float vx;
    float vy;
    glm::vec4 v_Color;
    unsigned int id;

    Object(float _x, float _y,
        float _vx, float _vy,
        glm::vec4 _v_Color, unsigned int _id)
        : x(_x), y(_y), vx(_vx), vy(_vy), v_Color(_v_Color), id(_id)
    {}
};

std::vector<Object> objects;
std::vector<Object> red;
std::vector<Object> green;
std::vector<Object> blue;
std::vector<Object> yellow;

void Rule(std::vector<Object>* group1, std::vector<Object>* group2, float G)
{
    float g = G;
    for (int i = 0; i < group1->size(); i++) {
        Object& p1 = (*group1)[i];
        float fx = 0;
        float fy = 0;
        for (int j = 0; j < group2->size(); j++) {
            const Object& p2 = (*group2)[j];
            float dx = p1.x - p2.x;
            float dy = p1.y - p2.y;
            float r = std::sqrt(dx * dx + dy * dy);
            if (r < 80 && r > 0) {
                fx += (dx / r);
                fy += (dy / r);
            }
        }

        p1.vx = (p1.vx + fx) * 0.5;
        p1.vy = (p1.vy + fy) * 0.5;
        p1.x += p1.vx;
        p1.y += p1.vy;
        if ((p1.x >= 800) || (p1.x <= 0)) { p1.vx *= -1; }
        if ((p1.y >= 700) || (p1.y <= 0)) { p1.vy *= -1; }
        std::cout << "Calculated velocity: " << fx << ", " << fy << std::endl;
        std::cout << "ID: " << p1.id << ", Velocity " << p1.vx << ", " << p1.vy << " Position: " << p1.x << ", " << p1.y << std::endl;
    }
}

std::vector<Object> CreateObjects(unsigned int number, glm::vec4 color)
{
    std::vector<Object> group;
    for (int i = 0; i < number; i++) {
        float x = rand() % 750 + 50;
        float y = rand() % 550 + 50;
        Object o(x, y, 0, 0, color, objects.size());
        group.push_back(o);
        objects.push_back(o);
    }
    return group;
}

int main()
{
    yellow = CreateObjects(10, glm::vec4(1.0f, 1.0f, 0.0f, 1.0f));
    blue   = CreateObjects(10, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f));
    green = CreateObjects(10, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
    red = CreateObjects(10, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
    
    Rule(&green, &green, -0.32);
    Rule(&green, &red, -0.17);
    Rule(&green, &yellow, 0.34);
    Rule(&red, &red, -0.1);
    Rule(&red, &green, -0.34);
    Rule(&yellow, &yellow, 0.15);
    Rule(&yellow, &green, -0.2);
    Rule(&blue, &green, -0.2);

    return 0;
}

额外说明

  • 把main函数返回类型从void改为int,符合C++标准。
  • 使用构造函数初始化列表初始化结构体成员,代码更规范高效。
  • 对只读的p2使用const Object&,避免不必要拷贝,同时防止误修改。

内容的提问来源于stack exchange,提问作者TwoLeggedCat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:18:37