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
相关产品推荐
相关产品推荐

