我正在开发一个程序,该程序通过高斯消除来解决矩阵形式的方程组。但是,我遇到了一个有趣的问题:如果我的算术运算符通过引用传递,则行的规范化将导致错误的结果。

在我的实现中,矩阵由多个 vector 组成,因此行运算仅是 vector 算术。以下是相关功能:

vector :

T& operator[] (const int i);
const T& operator[] (const int i) const;
Vector<T>& operator/=(const T& rhs);

template<class T>
Vector<T>& Vector<T>::operator/=(const T& rhs)
{
  if (rhs == 0)
  {
    throw DivideByZeroException();
  }
  for (int i = 0; i < _size; ++i)
  {
    _data[i] /= rhs;
  }
  return *this;
}

矩阵:
Vector<T>& operator[] (const int i);
const Vector<T>& operator[] (const int i) const;

(通过这种方式,单个[]用于访问行,而 double [] []用于访问元素。)

现在,这是导致问题的行:
mat[i] /= mat[i][i];

这里的问题是此操作在某个时候修改了mat[i][i],然后使用修改后的值,因为operator/=使用了按引用传递。

问题:最好将运算符(和所有类似的运算符)更改为按值传递,还是仅更改引起问题的行?是否假定所有运算符都将作为引用,从而使上述那条线通常不好?

最佳答案

实际上,我认为我想对我的评论做一个完整的回答,问题不在于您的/=运算符的实现,而在于调用者线路itsel。就像我说的那样,这不应产生可预测的(合法)结果。因为该语言在标准中说得很清楚,并提供了i = i++ + ++i;作为此事实的示例行。

因此,我的建议是不要试图使此事情成为您对客户的一种善意姿态,因为这样做的客户违反了比您的类(class)规范更为重要的契约(Contract)。

07-22 04:25
查看更多