C++类vector<int>成员存储int值循环后丢失问题求解
问题根因
你遇到的vector写入值后丢失的问题,和vector本身的存储逻辑无关,基本是两类低级编码错误导致:
- 把
Name_values类的实例声明写在了输入循环体内部。每次循环迭代都会生成一个全新的局部类对象,你断点看到的"临时写入成功",只是把值写到了当前轮次的临时对象里,进入下一轮循环时上一轮的临时对象会被直接销毁,数据自然全部丢失。等循环结束要输出结果时,你拿到的要么是循环外声明的从未写入过数据的空对象,要么是最后一轮刚初始化的空对象,自然读不到之前存的值。 addValue方法实现或调用逻辑有误:要么是方法内部定义了和类成员vector同名的局部变量,所有写入操作都落到了局部变量上,方法执行完局部变量被释放,类成员属性根本没被改动;要么是调用addValue时操作的是原对象的拷贝(比如值传递传参、操作函数返回的临时对象),写入操作没有作用到你最终用来输出的原对象上。
另外补充一个和需求相关的实现错误:如果你的类里存值的成员是vector<int>类型,根本没法实现"同名星期对应值追加到对应条目"的要求,必须用vector<vector<int>>类型,给每个星期名单独关联一个存int值的vector,才能做到同名值追加、条目一一对应。
修复步骤
按下面的顺序调整代码即可解决问题:
- 把
Name_values类的实例声明移到输入循环的外部,保证整个输入流程操作的是同一个持久存在的对象:
// 错误写法:对象声明在循环内,每次迭代重建 // while (cin >> name) { // Name_values nv; // // 写入操作 // } // 正确写法:循环外声明唯一实例 Name_values nv; string name; int val; while (cin >> name) { if (name == "q") break; cin >> val; nv.addValue(name, val); }
- 修正
addValue方法的实现,确保直接操作类成员属性,不要用局部变量覆盖成员:
class Name_values { private: vector<string> week_names; vector<vector<int>> week_values; // 每个name对应一个独立的int数组,支持追加 public: void addValue(const string& name, int input_val) { // 先遍历查找是否已经存在同名星期 for (int i = 0; i < week_names.size(); i++) { if (week_names[i] == name) { week_values[i].push_back(input_val); // 直接操作成员vector return; } } // 不存在同名条目就新增 week_names.push_back(name); week_values.push_back({input_val}); } // 这里自己实现按格式输出的方法即可 void printAll() { for (int i = 0; i < week_names.size(); i++) { cout << week_names[i] << ": "; for (int v : week_values[i]) { cout << v << " "; } cout << endl; } } };
- 检查所有调用
addValue的位置,不要操作类对象的拷贝:如果需要把类对象传给其他函数,一律用引用传递,不要值传递;不要对着函数返回的临时类对象调用addValue。
验证方式
改完后断点调试可以观察到,每次调用addValue后,同一个nv实例的week_names和week_values长度是持续累加的,循环结束后数据不会丢失,输入"q"退出后调用printAll方法就能按要求输出所有星期和关联的数值。
内容的提问来源于stack exchange,提问作者Frederick Anderson
相关产品推荐
相关产品推荐

