C++遍历类对象数组时出现溢出问题求助
问题描述
使用范围for循环遍历PayRoll类对象数组,调用类函数修改double类型成员时出现负溢出问题。推测问题源于循环中操作的是数组对象的副本而非原数组,需要用指针或引用修复,但不知如何实现,希望用已学的简单方案解决。
相关代码
PayRoll.h
#pragma once #include <string> #include <iostream> using namespace std; class PayRoll { private: double payRate; double hoursWorked; public: // Public member to allow outside functions to access employee names string name; //Constructor PayRoll(string, double, double); void setHoursWorked(double); double getGrossPay() const { double grossPay; grossPay = hoursWorked * payRate; cout << hoursWorked << endl; cout << payRate << endl; cout << grossPay << endl; return grossPay; } };
PayRoll.cpp
#include "PayRoll.h" #include <string> using namespace std; // Constructor PayRoll::PayRoll(string employee, double rate, double hours) { name = employee; payRate = rate; hoursWorked = hours; } // Function to set hours worked void PayRoll::setHoursWorked(double hours) { hoursWorked = hours; }
main.cpp
#include <iostream> #include "PayRoll.h" #include <iomanip> using namespace std; int main() { // Initializing an array of PayRoll objects const int NUMEMPLOYEES = 7; PayRoll employees[NUMEMPLOYEES] = { {"Annie", 15.50, 0}, {"Bob", 14.75, 0}, {"Callie", 18.65, 0}, {"Derick", 18.65, 0}, {"Evelyn", 22.45, 0}, {"Frankie", 22.65, 0}, {"Gertrude", 25.45, 0}, }; cout << "Please enter the hours worked by each employee." << endl; // Prompts the user to enter hours worked for each employee //ISSUE MAY BE STEMMING FROM HERE, USE A POINTER INSTEAD OF A COPY for (PayRoll person : employees) { cout << "How many hours did " << person.name << " work this week?" << endl; double hours; cin >> hours; while (hours < 0 || hours >60) { cout << "Please enter a number of between 0 and 60 for the week." << endl; cin >> hours; } person.setHoursWorked(hours); } // Displays all the employees' gross pay //ISSUE MAY BE STEMMING FROM HERE, USE A POINTER INSTEAD OF A COPY cout << endl << "Here is what everyone earned this week." << endl << endl; for (PayRoll person : employees) { cout << person.name << " earned $" << setprecision(2) << fixed << person.getGrossPay() << endl; } return 0; }
解决方案
你的推测完全正确:范围for循环中PayRoll person : employees会创建数组中每个对象的副本,修改副本的成员变量不会影响原数组里的对象。最终计算工资时,原对象的hoursWorked还是初始值0,出现的负溢出数值大概率是输出时的异常显示,核心问题是副本导致的修改无效。
最简单的修复方案是将范围for循环的变量改为引用,这样操作的就是原数组中的对象:
- 修改输入小时数的循环:
for (PayRoll& person : employees) // 添加&,将变量改为原对象的引用 { cout << "How many hours did " << person.name << " work this week?" << endl; double hours; cin >> hours; while (hours < 0 || hours >60) { cout << "Please enter a number of between 0 and 60 for the week." << endl; cin >> hours; } person.setHoursWorked(hours); }
- 修改显示工资的循环(用const引用更高效,避免不必要的拷贝,且符合只读操作的语义):
for (const PayRoll& person : employees) // 使用const引用 { cout << person.name << " earned $" << setprecision(2) << fixed << person.getGrossPay() << endl; }
修改后,输入的小时数会直接作用于原数组中的对象,计算工资时就能得到正确结果,异常数值问题也会随之解决。
内容的提问来源于stack exchange,提问作者Fate
相关产品推荐
相关产品推荐

