Array Subscription: returning Reference vs proxy class method

北城余情 提交于 2020-01-02 19:28:09

问题


While searching for methods for overloading Subscript('[]') operator for template class, I came across two different techniques.

First Technique:

Overloading the operator [] returning pointer to the container directly, which will allow both reading value and assigning value. A sample implementation of this technique:

template <class T>
class X
{
    int _size;
    T *container;
public:
    X(int sz)
    {
        _size=sz;
        container=new T[sz]();
    }
    ~X()
    {

    }

    T& operator [](int indx)
    {
        return container[indx];
    }

};

With main() as:

X<int> sample(100);
cout<<sample[9]<<endl;
sample[9]=9;
cout<<sample[9]<<endl;

Output:

0
9

Second Technique:

Second technique involves declaring a proxy class and overloading the operator = via that class. A sample implementation of this technique:

template <class T>
class X
{
    int _size;
    T *container;
public:
    X(int sz)
    {
        _size=sz;
        container=new T[sz]();
    }
    ~X()
    {

    }

    class Proxy
    {
        int indx;
        X<T> &parent;
    public:
        Proxy(X<T> &p, int x) : parent(p),indx(x)
        {

        }
        void operator =(T assgn)
        {
            parent.container[indx]=assgn;
        }
        operator T const &()
        {
            return parent.container[indx];
        }
        friend class X<T>;//unnecessary line, I know!
    };
    Proxy operator[](int indx)
    {
        return Proxy(*this,indx);
    }

};

With same main() we get same output.

I personally like the second method. But, I really want to compare these two methods. What are the major functional difference of these two techniques. What advantages each of these method have?


回答1:


The proxy-based technique you describe can be used if you want to expose a sequence of elements that are not stored as-such (requiring a conversion from and to storage) or that cannot simply be accessed by-reference. An example is std::vector < bool >: it packs eight bools in every byte (one in each bit) in storage. Storing them that way, it is not possible to return a reference to a single such bool, so the index operator returns a "proxy-object" instead to support reading and writing of the contained bools.

If you can return a direct reference to the stored objects, there is no real advantage to wrapping it in a proxy unless you want to restrict the assignment (only allow positive values in the container for example).




回答2:


Usually, a proxy is used when you want to return something that doesn't match the internal storage of the data. The classic example is a 2D matrix, with elements stored in a single array. If you provide an operator to return rows or columns, you need proxies. Another example is the infamous std::vector<bool>, where the data need not be stored as a block of bool, but access must return bool to the user.

Proxies can be used to return different "views" of segments of an internal data representation. In your example, there seems no reason to use them.




回答3:


Getting proxy objects right for most client usage is considerably trickier... for example - what if someone says:

tcp_peer.send_from_iterator_range(&sample[2], &sample[7+1]);

If sample::operator[] returns a temporary proxy, and that proxy doesn't carefully replace operator&, then the code asks for the addresses of the proxies themselves.

Some client usage just can't be supported without losing the Proxy's ability to intercept reads and/or writes to the data, for example in...

Container::element_type& ref = container[n];
ref = 20;

...the client code assumes the container's operator[] will yield a reference to an actual element. Any proxy returned by operator[] must either provide an operator element_type&() - handing over such a reference and taking itself out of play - or refuse to (e.g. only return a const reference, return a temporary by value to which a non-const reference can't be bound) and force edits to the client code.

So, proxy's are 95% as good when you need them, but best avoided when you don't.



来源:https://stackoverflow.com/questions/22980171/array-subscription-returning-reference-vs-proxy-class-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!