[Effective-cpp] Item 30: Proxy Classes
David.Nash at wallstreetsystems.com
David.Nash at wallstreetsystems.com
Mon Jun 9 10:01:28 EDT 2003
At last, here it is. Sorry about the delay:
More Effective C++
Item 30: Proxy Classes
This is another longish item as it deals with another fairly complicated
issue: Proxy classes, objects of which stand-in for instances of other classes
or built-in types.
Why might you need a stand-in for another object? The first rationale Scott
gives goes as follows:
You might want to write a "smart 2D array", kind of like a std::vector but in
two dimensions. you want to declare it like this:
Array2D<int> data(10,20)
and use it like this:
data[3][6]
Unfortunately there is no [][] operator you can define for user-define types,
so you can't do this. The answer is to define operator[] to return a proxy
object, an Array1D, and to define operator[] for that class to access the
other dimension.
The trick is that the user never sees the proxy objects, in a perfect world
they wouldn't even know they exist.
However the world is far from perfect and there are a number of restrictions
on what you can do with proxy objects.
First however, another example is given. This time the proxy stands in for a
char (or other type) returned from a string (it could be any container,
really).
Why? The basic idea is that if we are reference counting, especially if we are
using the much discussed and generally discredited Copy On Write, it is
advantageous to know whether operator[] is being used to return an lvalue
(which is being written to, and may need expensive copying to be performed) or
an rvalue (which is not and consequently doesnt). Unfortunately you can't
provide a different implementation because you can't overload on const-ness of
return value.
So the answer is to delay the decision by returning a proxy that stands in for
the char, and which has an assignment operator that causes the C.O.W. (or
whatever) to be performed. If the char is used as an rvalue, the assignment
operator is never called - the cheap conversion to char operator is called
instead.
Now, to return to the problems with proxies, they mostly stem from the fact
that the proxy objects dont behave exactly like the objects they are standing
in for. For instance, if you try to take the address of a char from a string
that returns proxies, as described above, you would find that you are taking
the address of the proxy not of the char it represents. Also a proxy for a
given class doesnt have the same member functions as the class it stands for.
The result is that you need to give the proxy member functions for all the
member functions in the object being held.
More information about the Effective-cpp
mailing list