运算符重载疑问:Polynomial一元减操作为何修改原对象?求解决方案
问题分析与解决方案
问题根源
你在Polynomial的一元减运算符里犯了引用赋值的错误:
Polynomial result = polynomial;
这行代码并没有创建新的Polynomial对象,result和传入的polynomial指向的是同一个内存实例。所以当你遍历result.container修改里面的Symbol时,实际上是直接修改了原polynomial对象的容器内容,导致原对象被篡改。
而Symbol的一元减运算符是正确的,因为它返回了一个新的Symbol实例,完全没有修改原对象:
public static Symbol operator -(Symbol symbol) => new(symbol.symbol, -symbol.Coefficient, symbol.Exponent);
修复方案
修改Polynomial的一元减运算符,核心是创建一个全新的Polynomial实例,所有修改都在新实例上进行,避免影响原对象。
方法1:创建新实例并逐个添加取反后的Symbol
public static Polynomial operator -(Polynomial polynomial) { // 生成全新的Polynomial实例,和原对象彻底解耦 Polynomial result = new Polynomial(); foreach (var symbol in polynomial.container) { // 利用Symbol的一元减得到新对象,添加到新容器中 result.container.Add(-symbol); } return result; }
方法2:基于原容器副本创建新实例(适用于带容器构造函数的Polynomial)
如果你的Polynomial类有接收容器的构造函数,可以先复制原容器的副本,再修改副本:
// 先确保Polynomial有这样的构造函数: // public Polynomial(List<Symbol> container) // { // this.container = new List<Symbol>(container); // 复制原列表,而非引用 // } public static Polynomial operator -(Polynomial polynomial) { // 基于原容器的副本创建新Polynomial Polynomial result = new Polynomial(polynomial.container); for (int i = 0; i < result.container.Count; i++) { // 修改副本里的元素,不会影响原对象 result.container[i] = -result.container[i]; } return result; }
验证效果
修改后执行测试代码,就能得到预期结果:
Console.WriteLine(polynomial); // 输出: 3*x + 2*y Console.WriteLine(-polynomial); // 输出: -3*x - 2*y Console.WriteLine(polynomial); // 输出: 3*x + 2*y(符合预期)
内容的提问来源于stack exchange,提问作者Haydara
相关产品推荐
相关产品推荐

