Two array subscript overloading to read and write

2019-06-08 19:04发布

问题:

I'd like to have a class with two array subscript operator overloads: one used for reading and the other for writing.

The pourpose is to keep a counter of changes. I read (at http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node97.html) that I could do something like this:

template<typename T>
class Array
{
public:
    Array()
    {
        data = new T[100];
    }

    T &operator[] (int index)
    {
        cout << "Is writing\n";
        changes++;
        return data[index];
    }

    T operator[] (int index) const
    {
        cout << "Is reading\n";
        return data[index];
    }

private:
    T *data;
    int changes;
};

But that doesn't work in my case. I'm using g++ 4.7 with -std=c++11 and actually only "Is writing" is printed on screen, even if I do:

Array<int> a;
a[0] = 3;
cout << a[0] << endl;

I also noticed that the latter is never called by inspecting the source with gcov. Is the method on that page completely wrong, or is something I'm misinterpreting?

Thanks in advance.

回答1:

This is only a rough idea and I haven't thought about all the implications, but a proxy class with overloaded assignment and cast operators could solve your problem:

template<typename T>
class CountingProxy
{
public:
    CountingProxy(int& counter, T& ref) : counter_(counter), ref_(ref)
    {
    }

    CountingProxy<T>& operator=(const T& o)
    {
        cout << "Is writing\n";
        counter_++;
        ref_ = o;
        return *this;
    }

    operator T()
    {
        cout << "Is reading\n";
        return ref_;
    }

private:
    int& counter_;
    T& ref_;
};

template<typename T>
class Array
{
public:
    Array()
    {
        data = new T[100];
    }

    CountingProxy<T> operator[] (int index)
    {        
        return CountingProxy<T>(changes, data[index]);
    }

    T operator[] (int index) const
    {
        cout << "Is reading\n";
        return data[index];
    }

private:
    T *data;
    int changes;
};

On the other hand, you probably would be better off by implementing separate functions for reading and writing elements of your array, such as T& get(int index), const T& get(int index) const and void put(int index, const T& value).



回答2:

const overloads are only called if this is const. It's not determined on whether it's a "read" or a "write" operation.