On Thursday 16 June 2005 19:19, Steven T. Hatton wrote:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1671.pdf
Overloading operator.() & operator.*() ...
We've been doing that for the YaST2 internal libraries for 5+ years (YCPValue and derived classes, YCPValueRep and derived classes). ... I'm confused. Are you saying you used non-standard language features in YaST? How closely did you look at that article? It was proposing a modification to the C++ standard that would permit the overloading of "operator().*", and "operator().". Neither of which are currently overloadable in standard C++.
Uh - sorry, maybe I didn't read the articly you posted thoroughly enough, and maybe my comments were misleading. What we did was to overload operator->() and split up our data container classes into a YCPSomething class and a YCPSomethingRep class. YCPSomethingRep holds the actual data, while YCPSomething is little more than a smart pointer - its overloaded operator->() takes care of actually accessing its corresponding YCPSomethingRep instance. The basic idea was to avoid null (and otherwise invalid) pointers, yet at the same time minimize data copying for function calls. etc. - and to do "shallow copies" whenever possible, since the YCP script language we developed for YaST2 (initially) was designed as a (somewhat) functional language that didn't support the notion of references of pointers, so you basically have to copy around lots of data - in function calls, when returning function results etc.; but of course you really don't want the interpreter to implement that by brute-force copying a function's return value - which might be a big object such as a list or a map where each element in turn can be any kind of big object. Rather, it does a "shallow copy" of those data, thus incrementing the reference count in some YCPSomethingRep object, which prevents it from being freed when the function returns. You get the picture. Still, that architecture tends to confuse people who are using that on the C++ level: You need a YCPSomething, but you have to be aware that this YCPSomething is only a ref-counted pointer, so you access almost all (but not _really_ all, and that's the downside) of its data or functions with YCPSomething->someFunc(), not, as you would expect it, with YCPSomething.someFunc(). Still, you have to check it for validity with YCPSomething.isNull(). OTOH you have to bear in mind that since it already is something like a reference, it makes little sense to pass it to a function with " const YCPSomething &" - you pass the real thing, while OTOH in the same function prototype you really want to use "const std::string &". Confused? Yes, sure, we, too. ;-) Maybe it is possible to hide all that confusion if it is designed and implemented properly, and maybe overloading operator.() and operator*() might help for that purpose. But IMHO since you need to keep thinking anyway when using C++ it's a much better idea not to add yet another layer of abstraction and thus complexity and remain honest with your C++ programmers: Make it absolutely clear what is an object and what is a pointer. Don't add to the confusion. It only adds to the burden they have to carry. CU -- Stefan Hundhammer <sh@suse.de> Penguin by conviction. YaST2 Development SUSE Linux Products GmbH Nuernberg, Germany