Overload = operator for class that shall behave li

2019-07-29 10:24发布

问题:

This question already has an answer here:

  • How to overload array index operator for wrapper class of 2D array? 2 answers

I've got a template of a class that shall behave like matrix. So the usecase is something like:

Matrix matrix(10,10);
matrix[0][0]=4;
//set the values for the rest of the matrix
cout<<matrix[1][2]<<endl;

When I set the values directly in the constructor, it works well, but when I want to use matrix[x][y]=z; I get error: lvalue required as left operand of assignment. I assume, that I must overload = operator. Nevertheless I tried whole evening and I didn't find out, how to implement it. Would anybody be please so kind and show me how to overload = operator for my code, to make it assign values to that matrix?

code:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <sstream>

using namespace std;

class Matrix {
public:

    Matrix(int x,int y) {
        _arrayofarrays = new int*[x];
        for (int i = 0; i < x; ++i)
            _arrayofarrays[i] = new int[y];

        // works here
        _arrayofarrays[3][4] = 5;
    }

    class Proxy {
    public:

        Proxy(int* _array) : _array(_array) {
        }

        int operator[](int index) {
            return _array[index];
        }
    private:
        int* _array;
    };

    Proxy operator[](int index) {
        return Proxy(_arrayofarrays[index]);
    }

private:
    int** _arrayofarrays;
};

int main() {
    Matrix matrix(5,5);

    // doesn't work :-S
    // matrix[2][1]=0;

    cout << matrix[3][4] << endl;
}

回答1:

If you intend to modify the element of the matrix referenced by the proxy, then the overload of operator[] in the Proxy class must return a reference:

int& operator[](int index)

At the moment, you return int, which makes a copy of the element’s value—not what you want. There ought to be a const overload as well, so that operator[] works on const matrices. This one can return by value:

int operator[](int index) const

And actually, size_t would be more appropriate for the index than int, since it’s an unsigned type. You aren’t giving any particular meaning to negative indices, so it makes sense to disallow them.

You don’t need to overload operator= of Proxy unless you want to assign a whole row at once. In fact, you don’t need the Proxy class at all, because you can just return a pointer to the row array directly. However, if you want to change your design—e.g., using a sparse or packed representation—then the Proxy would let you keep the m[i][j] interface.



回答2:

The issue is that you're returning an int value in proxy::operator[]. Your first [] operator returns the proxy object, the second returns an int. If your proxy [] operator were to return an int reference, then you would be able to assign to it:

int& operator[](int index) {
    return _array[index];
}