Path: utzoo!attcan!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.lang.c++ Subject: Re: Assignments to reference variables [ and operator.() ] Message-ID: <57865@microsoft.UUCP> Date: 1 Oct 90 20:37:22 GMT References: <8445@jarthur.Claremont.EDU> <57570@microsoft.UUCP> <1677@lupine.NCD.COM> <57684@microsoft.UUCP> <3833@osc.COM> Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Organization: Microsoft Corp., Redmond WA Lines: 74 In article <3833@osc.COM> tma@osc.UUCP (Tim Atkins) writes: | As I see it there is a very pragmatic reason for not allowing | operator . in C++. Namely that it would be very difficult to | distinquish normal use from the redefined use. For instance: | | class schitzy { | int a; | public: | operator . () { /* do something different here */ } | schitzy( schitzy& s){ | a = s.a; // what do I really mean??? | } | | }; | | I see no sane way to get back to the original operator . meaning | in the above case. Any takers? This "difficulty" is presumably what lead op. to not be allowed overloading in the first place. My proposal is that overloaded op. not be treated any differently than any other overloaded operator. Namely: if your code ever explicitly includes a dot with an instance of an overloading class on the lhs, you get the overloaded operator. In your example above, your use of dot gets you the overloaded version. How does one avoid getting the overloaded operator? By not using the dot. C/C++ provides synonyms that avoid using the dot: instead of: a = s.a; one can say: a = (&s)->a; Note, that like the other overloaded symbol operators, the compiler never implicitly calls the function behind your back -- the overloaded function only gets called when you write the symbol that is overloaded. So, in the important case of implicit this, you don't get the overloaded . operator -- anymore than you get the overloaded -> operator. int schitzy::aValue() { return a; } just returns the value of the local member. It doesn't implicitly call (*this).operator.().a; and it doesn't implicitly call this->operator->()->a; In the real domain of applicability of operator.() -- namely in "smart" reference classes -- these issues needn't arise in the first place. Consider writing a reference counted reference class: class FooRef { private: Foo* fooptr; public: FooRef(FOO& foo) : fooptr(&foo) { foo.incrementUsageCount(); } ~FooRef() { fooptr->decrementUsageCount(); } Foo& operator.() { return *fooptr; } Foo* operator&() { return fooptr; } // ... }; [[Note how much simpler and efficient reference counted references are compared to reference counted pointers]] I suspect that it would be difficult -- and truly schitzoid -- to try to write a class that acts simultaneously as a pointer and a reference. Anyone attempting such would get their just deserves.