3

我有一个自定义类,旨在为二维数组提供服务。我已经超载了+运算符,但得到了一些我没有预料到的奇怪结果。我在这里有复制和赋值构造函数:

Array<T, ROW, COL>& operator=(const Array<T, ROW, COL> &rhs) {
    if (this != &rhs) {
        // allocate new memory
        T *newData = new T[ROW * COL];
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < COL; j++) {
                newData[j*ROW + i] = rhs(i, j);
            }
        }
        data = newData;
    }
    return *this;
}

这是我的重载+运算符:

inline Array<T, ROW, COL> &operator+(const Array<T, ROW, COL> &rhs) {
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            this->data[j*ROW + i] += rhs(i,j);
        }
    }
    return *this;
}

这是一个部分main

Array<double, 10> ten;
ten.fill(10.0); // fill with tens
Array<double, 10> result = ten + ten + ten + ten;
std::cout << result << std::endl;

产量:

[0]: 80 
[1]: 80 
[2]: 80 
[3]: 80 
[4]: 80 
[5]: 80 
[6]: 80 
[7]: 80 
[8]: 80 
[9]: 80 

这对我来说没有意义。我会认为结果会一直如此40。如果您需要查看它们,我已经定义了复制和赋值构造函数。

我不明白什么?谢谢!

4

1 回答 1

13

不要,只是不要。operator+不应修改其任一操作数的内部状态。正确的原型是

Array<T, ROW, COL> operator+(Array<T, ROW, COL> lhs, const Array<T, ROW, COL> &rhs)
{
    //logic goes here
    return lhs;
}

如您所见,您按值返回并且不修改任何原始参数(第一个是按值传递的,但是由于您正在创建它的副本或在函数内创建一个新对象以返回它,因此通过值同样好 - 或者您可以通过const引用传递它)。如果您必须将其保留为成员(我写的是自由运算符),请将其原型为

Array<T, ROW, COL> Array::operator+(const Array<T, ROW, COL> &rhs) const;

注意const限定符,它告诉你(和读者)this没有被修改。

编辑:好的,终于找到了链接 -阅读这个

于 2013-06-05T19:44:18.037 回答