Two array subscript overloading to read and write

2019-06-08 18:48发布

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.

2条回答
放我归山
2楼-- · 2019-06-08 19:02

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

查看更多
放我归山
3楼-- · 2019-06-08 19:04

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).

查看更多
登录 后发表回答