C++类对象属性修改后重置为初始值问题排查
问题原因
代码的核心问题是值传递导致的临时副本修改失效。C++函数默认使用值传递传参:调用函数时,编译器会为传入的每个实参生成一份独立的临时拷贝,函数内部所有针对参数的修改都只作用在这份临时拷贝上,函数执行结束后临时拷贝被销毁,修改不会同步到main函数中定义的原始对象。
所有存在值传递问题的方法
Manager::cadastrarSala(Lista lista, Sala sala):传入的影厅列表是临时副本,函数内给列表添加影厅、修改列表长度的操作,完全不会影响main中定义的listaSalas对象,该对象的tamanho始终为初始值0。Manager::reservarSala(Lista lista, Sessao sessao):传入的影厅列表、场次对象都是临时副本,函数内修改影厅预留状态、给场次绑定影厅的操作,不会修改原始的listaSalas和sessao1对象。Vendedor::venderIngresso(Sessao sessao, int quantidade, Cliente cliente):传入的场次、客户对象都是临时副本:- 函数内执行
sessao.ingressos += quantidade修改的是临时场次副本的已售票数,原始sessao1的ingressos始终为初始值0 - 传入的客户对象是
cliente1的临时副本,调用compraIngresso修改的是副本的余额、已购票数属性,原始cliente1的属性始终保持创建时的初始值
- 函数内执行
Cliente::compraIngresso(Sessao sessao, int quantidade):传入的场次对象是临时副本,后续如果依赖该方法修改场次状态也会失效。
修复方法
将所有需要修改原始对象状态的参数改为引用传递,在参数类型后添加&符号,告知编译器直接引用原始对象,不生成临时副本:
- 修改
cadastrarSala的声明与实现:
// 类内声明 void cadastrarSala(Lista& lista, Sala sala); // 实现 void Manager:: cadastrarSala(Lista& lista, Sala sala){ lista.salas[lista.tamanho] = sala; lista.tamanho++; }
- 修改
reservarSala的声明与实现:
// 类内声明 Sala reservarSala(Lista& lista, Sessao& sessao); // 实现 Sala Manager:: reservarSala(Lista& lista, Sessao& sessao){ int i = 0; while(lista.salas[i].reservado == true){ i++; } lista.salas[i].reservado = true; sessao.sala = lista.salas[i]; return lista.salas[i]; }
- 修改
compraIngresso的声明与实现:
// 类内声明 int compraIngresso(Sessao& sessao, int quantidade); // 实现 int Cliente:: compraIngresso(Sessao& sessao, int quantidade){ dinheiro -= quantidade * sessao.preco; ingressosPossuidos += quantidade; cout<<name<<" agora possui "<<dinheiro<<" reais"<<endl; cout<<name<<" agora possui "<<ingressosPossuidos<<" ingressos"<<endl; return ingressosPossuidos; }
- 修改
venderIngresso的声明与实现:
// 类内声明 void venderIngresso(Sessao& sessao, int quantidade, Cliente& cliente); // 实现 void Vendedor::venderIngresso(Sessao& sessao, int quantidade, Cliente& cliente){ if(quantidade > (sessao.capacidade - sessao.ingressos)){ cout<<"Infelizmente o senhor "<<cliente.name<<" não conseguiu comprar os ingressos pois a sessão estava lotada!"<<endl; } else if ((quantidade * sessao.preco) > cliente.dinheiro){ cout<<"Infelizmente o senhor "<<cliente.name<<" não conseguiu comprar os ingressos pois não tinha dinheiro suficiente!"<<endl; } else { cout<<"O senhor "<<cliente.name<<" comprou "<<quantidade<<" ingressos para a sessão "<<sessao.filme<<"!"<<endl; sessao.ingressos += quantidade; cliente.compraIngresso(sessao, quantidade); } }
修改完成后运行程序,即可得到符合预期的输出:
O senhor Lucas comprou 5 ingressos para a sessão Avengers! Lucas agora possui 0 reais Lucas agora possui 5 ingressos Infelizmente o senhor Lucas não conseguiu comprar os ingressos pois não tinha dinheiro suficiente! O cliente Lucas tem 0 reais! O cliente Lucas tem 5 ingressos! A sessao Avengers tem 5 ingressos!
内容的提问来源于stack exchange,提问作者Hugo Folloni
相关产品推荐
相关产品推荐

