【发布时间】:2017-01-19 10:28:48
【问题描述】:
我目前正在用 C++ 编写一个Polynomial-class,它应该表示以下形式的多项式:
p(x) = a_0 + a_1*x^1 + a_2*x^2 + ... + a_i*x^i
其中a_0, ..., a_i 都是int 的。
该类内部使用std::vector<int> 类型的成员变量a_ 来存储常量因子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+-overloading(利用这种舒适的只读-operator[])失败了。
operator+-overloading:
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_ 时仍然出错。什么可能导致编译器在行中使用 read-write-实现:
res[i] += (*this)[k] * other[i-k];
尤其是等号右边的部分。
我确定该错误是由 read-and-write-operator[] 的“错误”使用引起的。因为通过额外的检查修复了无效访问:
if (k <= this->degree() && i-k <= other.degree()) {
res[i] += (*this)[k] * other[i-k];
}
使用operator[]-overloading 我缺少什么?为什么这里不使用只读-operator[]?
【问题讨论】:
-
二进制
operator*通常应该是const。 -
让
[ ]做不同的事情是违反直觉和令人困惑的。程序员期待同样的行为。 -
首选非会员
Polynomial operator*(Polynomial const& lhs, Polynomial const& rhs),因为您不需要对this的任何特权访问。是的,at会比神奇的[]更好,它有时会做你想做的事...... -
这个问题是一个很好的例子,说明完全没有尝试将代码缩小到相关部分。
-
但是你有没有问过自己读者是否想通读所有的上下文?我的意思是,这个问题写得很好,读起来很有趣,但是到最后,我现在可以想象一个十行版本的问题,它表达了同样的观点,我希望这就是那个问题。很抱歉选择了你,但很少看到有这个问题但总体上很好的问题。 (通常这个问题出现在完全没有希望的问题中。)
标签: c++ operator-overloading operators readonly read-write