C++实现ATM系统时array of objects数据被末位对象覆盖如何解决
问题概述
开发ATM SYSTEM程序时,尝试使用对象数组尽可能精简代码,但遇到数据异常问题:依次为数组中的后续对象录入取值时,数组中第一个、中间位置对象的取值会被最后一个对象的数据/值替换,最终所有对象存储的数据都与最后一个对象的数据一致,需要定位代码问题点,参考最优建议重新修正实现。
问题原代码
#include <iostream> #include <string> #include <vector> using namespace std; string Card_no,Account_no,Person_name; long int Pin_no,num; class Login { private : public : void setPerson_name(string D) { Person_name = D; } void setAccount_no(string C) { Account_no = C; } void setCard_no(string A) { Card_no = A; } void setPin_no(long B) { Pin_no = B; } string getPerson_name() { return Person_name; } string getAccount_no() { return Account_no; } string getCard_no() { return Card_no; } int getPin_no() { return Pin_no; } void accept_customer_details() { string person_name,account_number,card_number; long int pin_number; cout<<"\n Accepting Employee Details : \n"<<endl; cout<<"Enter the Person Name : "<<endl; cin>>person_name; cout<<"Enter the Account Number of the Person : "<<endl; cin>>account_number; cout<<"Enter the 16 digit ATM Card Number of the Person : "<<endl; cin>>card_number; cout<<"Enter the 4 digit ATM PIN NUMBER : "<<endl; cin>>pin_number; setPerson_name(person_name); setAccount_no(account_number); setCard_no(card_number); setPin_no(pin_number); } void display_customer_details() { string pnm,an,cn; int pn; pnm = getPerson_name(); an = getAccount_no(); cn = getCard_no(); pn = getPin_no(); cout<<"\n Displaying the Employee details : \n"<<endl; cout<<"The Person's Name : "<<pnm<<endl; cout<<"The Account Number of the Person : "<<an<<endl; cout<<"The 16 digit ATM Card Number of the Person : "<<cn<<endl; cout<<"The 4 digit ATM PIN NUMBER : "<<pn<<endl; } }; class Access : public Login { public : void account_ass(vector <Login> &VL,int sz) { num = sz; Login l[num]; string ucn,upn; //string CARD_NUMBER[sz],PIN_NUMBER[sz],ACC_NO[sz],P_NAME[sz]; int flag0 = 0,flag1 = 0,flag2 = 0,flag02 = 0; int chance = 3,c = 0,p = 0; for(int o = 0;o<num;o++) { cout<<"value of o is : "<<o<<endl; l[o] = VL[o]; cout<<"\n CARD_NUMBER IS HERE : "<<l[o].getCard_no()<<"\n AND ITS PIN NUMBER IS : "<<l[o].getPin_no()<<endl; cout<<"The Account Number is : "<<l[o].getAccount_no()<<" \n Person's Name is : "<<l[o].getPerson_name()<<endl; cout<<"Object :"<<o+1<<" address : "<<&l[o]<<endl; } } }; int main() { int N; cout<<"Enter how many person's details you want to add :- "<<endl; cin>>N; Login lg[N]; //Access ac[N]; vector <Access> ac; Access a; vector <Login> vl; for(int K = 0;K<N;K++) { ac[K].accept_customer_details(); } for(int I=0;I<N;I++) { ac[I].display_customer_details(); vl.push_back(ac[I]); } a.account_ass(vl,N); return 0; }
问题根因
- 核心错误:所有存储用户数据的变量
Card_no、Account_no、Person_name、Pin_no、num都被定义为全局变量,而非Login类的成员变量。全局变量在程序运行期间仅存在唯一一份内存空间,所有Login、Access类的实例调用set、get方法时,操作的都是这同一份全局数据,没有属于实例自身的独立存储空间。每次录入新用户数据都会直接覆盖全局变量里的旧值,最终所有对象读取到的必然是最后一次录入的内容。 - 附加逻辑/语法错误:
- 主函数中定义的
vector<Access> ac初始为空,未提前分配空间就直接通过ac[K]下标访问写入,属于内存越界操作,会触发未定义行为,大概率直接导致程序崩溃。 - 代码中使用了
Login l[num]、Login lg[N]这类变长数组写法,不属于标准C++语法,仅为部分编译器的非标准扩展,跨环境兼容性极差。
- 主函数中定义的
修正方案
- 将原本定义在全局作用域的用户数据变量,全部移动到
Login类的私有成员区域,保证每个类实例持有独立的数据副本,从根源上解决数据互相覆盖的问题。 - 移除所有变长数组写法,需要动态长度的集合统一使用
std::vector管理,避免兼容性问题和内存越界风险。 - 修正主函数中vector的操作逻辑:录入用户数据时先创建临时对象完成数据录入,再将对象push到vector中,禁止对空vector直接做下标访问。
内容的提问来源于stack exchange,提问作者Siddharth Lodha
相关产品推荐
相关产品推荐

