Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!jarthur!petunia!kestrel.edu!gyro From: gyro@kestrel.edu (Scott Layson) Newsgroups: comp.lang.c++ Subject: Re: Overloaded operator dot? Message-ID: <1991Mar25.194812.6676@kestrel.edu> Date: 25 Mar 91 19:48:12 GMT References: <624@taumet.com> <12193@pasteur.Berkeley.EDU> <4610@lupine.NCD.COM> Organization: Kestrel Institute, Palo Alto, CA Lines: 79 In article <4610@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes: >I claim that even if you *had* your so-called "smart references" today, >there is absolutely nothing that you could do with them that you could >not do just as well using only "smart pointers". > >I also claim that there is nothing that you could do significantly *easier* >with "smart references" than you could with just smart pointers. > >If you have a counterexample I encourage you to post it and prove me wrong. >(Post the code please. Hemming and hawing in flowery prose will not help >to make the point either way.) Here's something I actually tried to do, with encouragement from an experienced C++ programmer, and ran head-on into the absence of overloadable `.'. I wanted to be able to define "active slots" of objects -- sortof like member variables, but with the option of running arbitrary code when the slot was read or written. (This idea was inspired by other object-oriented systems I have used.) So, let's say I have an object `foo', of class `Frob', with a slot `name' of type `symbol'; I want to be able to use the expression `name(foo)' to read the name, and `name(foo) = bar' to write it (there was a reason why I used `name(foo)' rather than `foo.name()', but it doesn't matter here). The way I went about this was to create a class called `_Frob_name' (these declarations were being automatically generated, by the way) such that 1) the implicit conversion from `_Frob_name' to `symbol' (the type of the `name' slot) would run the "read demons", and 2) `_Frob_name::operator=' was overloaded to run the "write demons". The declarations to accomplish this are not hard to generate, but since you ask, they look basically like this: class Frob { // whatever private members public: friend class _Frob_name; friend _Frob_name name(Frob); }; class _Frob_name { Frob _Frob; _Frob_name(Frob f) { _Frob = f; } public: friend name(Frob); operator symbol(); symbol operator=(symbol); }; inline _Frob_name name(Frob f) { return _Frob_name(f); } _Frob_name::operator symbol() { // run "read demons" symbol& val = // however you get a reference to the `name' of _Frob return val; } symbol _Frob_name::operator=(symbol s) { // run "write demons" symbol& val = // however you get a reference to the `name' of _Frob val = s; return s; } The problem, anyhow, is that (supposing `symbol' has a member function `hash') I can't say `name(foo).hash()'. Could I have made this work by using pointers to the intermediate class `_Frob_name' instead of instances thereof? No, because then I couldn't overload `operator='. -- Scott Layson Burson Gyro@Reasoning.COM