1

2つの配列添え字演算子のオーバーロードを持つクラスが必要です。1つは読み取りに使用され、もう1つは書き込みに使用されます。

目的は、変化のカウンターを維持することです。私は( http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node97.htmlで)次のようなことができると読みました:

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;
};

しかし、私の場合はうまくいきません。-std = c++11でg++4.7を使用していますが、実際には、次の場合でも「書き込み中」のみが画面に出力されます。

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

また、gcovでソースを調べることによって、後者が呼び出されることはないことにも気づきました。そのページの方法は完全に間違っていますか、それとも私が誤解しているものですか?

前もって感謝します。

4

2 に答える 2

5

constオーバーロードは、がである場合にのみ呼び出されthisますconst。それが「読み取り」操作であるか「書き込み」操作であるかは決定されません。

于 2012-05-28T17:46:06.700 に答える
2

これは大まかなアイデアであり、すべての影響については考えていませんが、オーバーロードされた割り当てとキャスト演算子を使用したプロキシクラスで問題を解決できます。

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;
};

一方、配列の要素の読み取りと書き込みには、、、などの個別の関数を実装する方がよいT& get(int index)でしょconst T& get(int index) constvoid put(int index, const T& value)

于 2012-05-28T18:05:50.200 に答える