Money类重载除法运算符后实例被意外修改的问题解决求助
问题分析与解决方案
你的问题核心在于重载的operator/违背了除法的常规语义:内置类型的除法(比如int a=100; int b=a/2;)不会修改原变量a,但你的实现直接修改了调用运算符的对象(也就是money_temp)的内部状态,这才导致了意外修改。
为什么会出现这个问题?
看你的operator/实现:
Money& Money::operator/(double i) { division(i); // 这里直接修改了当前对象的money_number return *this; }
division(i)会把当前对象(money_temp)的money_number除以i,然后你返回了这个被修改后的对象的引用——哪怕你去掉了&返回副本,原对象已经被division修改了,所以问题依然存在。
正确的实现方式
除法运算符应该返回一个新的对象,而不是修改原对象。我们需要在不改变原对象的前提下,计算出除法结果并返回:
方案1:基于副本修改后返回
修改头文件的声明:
Money operator/(double); // 去掉引用符号,返回值而非引用
然后修改运算符实现:
Money Money::operator/(double i) { // 先复制当前对象到临时副本 Money result = *this; // 只修改副本的数值 result.money_number /= i; // 返回这个副本 return result; }
方案2:直接构造新对象返回(更简洁)
如果你的Money类有接受double类型的构造函数,可以直接计算后返回新对象:
Money Money::operator/(double i) { return Money(money_number / i); }
这样修改后,执行mmm = money_temp / 2;时,money_temp的内部值不会被改变,因为我们始终只操作它的副本或者新创建的对象,完全符合除法的预期行为。
额外建议
如果希望支持类似2 / money_temp这样的反向除法操作,建议把operator/实现为非成员函数,同时声明为友元(如果需要访问私有成员),比如:
// 头文件声明 Money operator/(double lhs, const Money& rhs); // 实现 Money operator/(double lhs, const Money& rhs) { return Money(lhs / rhs.money_number); }
这样就能覆盖更多的除法场景啦。
内容的提问来源于stack exchange,提问作者香辛料
相关产品推荐
相关产品推荐

