C++ dispenserType类重复调用默认构造 自定义值被覆盖问题
问题根因
值与赋值不符的核心原因是变量作用域规则+多实例独立存储,和构造函数逻辑无关:
staffDispenser()内if/else分支中声明的dispenserType dt是块级局部变量,仅在当前分支的大括号范围内有效,离开代码块就会被系统销毁,无法被外部函数访问main函数开头声明的dispenserType dt是完全独立的另一个类实例,声明时默认调用无参构造将所有参数初始化为50,staffDispenser()内创建的局部对象和该实例无任何关联,因此读取时只能拿到默认值- 原代码存在额外语法问题:
name、juice、c变量未定义,main函数中的item、cost数组全程未写入有效值,直接输出会读取未初始化的内存垃圾值
修复方案
核心思路是仅创建一次类实例,跨函数传递实例引用,避免重复创建对象触发无参构造覆盖参数,完全符合不允许删除两个构造函数的作业要求:
- 调整
staffDispenser函数返回值类型,让其直接返回初始化完成的dispenserType对象,不在函数内部生成用完即销毁的局部对象 - 其他需要操作售货机的函数(比如要求实现的
customerDispenser),通过引用传参的方式接收已经初始化好的实例,不要在函数内部重新声明dispenserType变量创建新对象 - 补全原代码缺失的变量定义,修正变量读写逻辑的错误
修复后可运行代码
#include <iostream> #include <string> using namespace std; // 补全原代码缺失的商品名数组定义 const string name[4] = {"Coke", "Juice", "Water", "Snack"}; class dispenserType { private: int numberOfItems[4] = {0,0,0,0}; int cost[4] = {0,0,0,0}; public: // 保留作业要求的两个构造函数,不做修改 dispenserType() { for (int i = 0; i < 4; i++) { numberOfItems[i] = 50; cost[i] = 50; } } dispenserType(int item[], int c[]) { for (int i = 0; i<4;i++){ numberOfItems[i] = item[i]; cost[i] = c[i]; } } int getNoOfItems(int i) { return numberOfItems[i]; } int getCost(int i) { return cost[i]; } void makeSale(int i) { numberOfItems[i] -= 1; } }; // 修改函数返回值为dispenserType,返回初始化完成的实例 dispenserType staffDispenser() { char choice; int item[4]; int cost[4]; cout << endl << "Do you want to asign values manually for each items? (Y for yes, N for no): "; cin >> choice; if (choice == 'Y' || choice == 'y') { for (int i = 0; i < 4; i++) { cout << "Enter the number of " << name[i] << ": "; cin >> item[i]; cout << "Enter the cost of " << name[i] << " (in cents): "; cin >> cost[i]; } // 返回使用自定义参数构造的对象 return dispenserType(item, cost); } else { cout << endl << "Each item is set to 50 in quantity and also cost 50 cents" << endl; // 返回使用默认参数构造的对象 return dispenserType(); } } // 顾客功能函数示例:通过引用接收已初始化的实例,不会触发构造函数重置值 void customerDispenser(dispenserType &dt) { // 此处编写顾客购买、查询等逻辑,直接操作传入的实例即可 cout << endl << "Current item stock and price:" << endl; for (int i =0; i<4; i++){ cout << name[i] << ": stock=" << dt.getNoOfItems(i) << ", price=" << dt.getCost(i) << " cents" << endl; } } int main() { // 仅创建一次实例,接收staffDispenser返回的初始化完成的对象 dispenserType dt = staffDispenser(); int stock[4]; int price[4]; // 读取商品参数 for (int i = 0; i < 4; i++) { stock[i] = dt.getNoOfItems(i); price[i] = dt.getCost(i); } // 输出校验结果 cout << endl << "Final stock value: "; for (int i =0; i<4; i++){ cout << stock[i] << " "; } cout << endl; cout << "Final price value: "; for (int i =0; i<4; i++){ cout << price[i] << " "; } // 调用顾客功能,传入已初始化的实例 customerDispenser(dt); return 0; }
编码注意事项
- 不要在代码块(
if/for/while包裹的大括号内部)声明需要跨块、跨函数使用的对象,局部变量离开作用域会被直接销毁,外部无法访问 - 所有需要操作同一售货机数据的函数,统一通过引用传递的方式传入已经初始化好的实例,不要在函数内部重新声明
dispenserType dt创建新实例,就不会触发无参构造重置参数 - 如果后续需要在多个模块中共享同一个售货机实例,也可以将实例定义为全局变量,但引用传递的方式代码耦合度更低,更推荐使用
内容的提问来源于stack exchange,提问作者I Forgot My Name
相关产品推荐
相关产品推荐

