为什么不使用只读[]运算符?

时间:2017-01-19 10:28:48

标签: c++ operator-overloading operators readonly read-write

我目前正在用C ++写一个Polynomial - 类,它应该代表以下形式的多项式:

p(x) = a_0 + a_1*x^1 + a_2*x^2 + ... + a_i*x^i

其中a_0, ..., a_i都是int&#39>。

该类在内部使用类型为a_的成员变量std::vector<int>来存储常量因子a_0, ..., a_i。要访问常量因子,operator[]将按以下方式重载:

读写:

int &operator[](int i)
{
  return a_.at(i);
}

尝试使用以下内容更改其中一个因素a_i时,这将失败

i > degree of polynomial = a_.size() - 1

只读:

int operator[](int i) const
{
  if (i > this->degree()) {
    return 0;
  }

  return a_.at(i);
}

稍微不同的实现允许在两个不同大小的多项式的因子上相当舒适地循环(不用担心多项式的度)。

可悲的是,我似乎错过了一些内容,因为operator+ - 重载(使用这个舒适的只读 - operator[])失败。

operator+ - 超载

Polynomial operator*(const Polynomial &other) {
  Polynomial res(this->degree() + other.degree());

  for (int i = 0; i <= res.degree(); ++i) {
    for (int k = 0; k <= i; ++k) {
      res[i] += (*this)[k] * other[i-k];
    }
  }

  return res;
}

不要介意所涉及的数学。重要的是,i总是在

的范围内
0 <= i < res.a_.size()

因此写入res[i]是有效的。但是,(*this)[k]other[i-k]会尝试从不一定位于[0, (*this).a_.size() - 1]范围内的指数中读取。

我们的只读 - 实现operator[]权限应该没问题吗?尝试在无效索引处访问a_时仍然出错。什么可能导致编译器在行中使用读写 - 实现:

res[i] += (*this)[k] * other[i-k]; 

尤其是平等右侧的部分。

我确定错误是由&#34;错误&#34;使用读写 - operator[]。因为附加检查修复了无效访问:

if (k <= this->degree() && i-k <= other.degree()) {
  res[i] += (*this)[k] * other[i-k];
}

使用operator[] - 重载时我错过了什么?为什么只读 - operator[]在这里使用?

1 个答案:

答案 0 :(得分:6)

(*this)[k]正在使用非const this,因为包含它的函数不是const

因此编译器首选[]的非常量重载。

你可以使用丑陋的const_cast来解决这个问题,但实际上你应该保持[]运算符的两个版本的行为尽可能相似。此外,std::vector的{​​{1}}重载并不强制检查绑定的索引,而必须是[]。您的代码与此有所不同,因此可能会使您的代码感到困惑。