You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运算符重载疑问: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 02:10:52