mckenney@sri.com (Paul E. McKenney) (03/16/88)
Several c++ gurus around here told me that it is usually bad practice to allow explicit access to instance variables in c++, that it was better to define member functions to do the job. This seemed very strange to me until I found that c++ does not allow redefinition of the `.name' operators. Of course, if you cannot redefine these functions, then allowing explicit access to the instance variables will `freeze' the representation of the object -- bad for software maintenance. So, why doesn't c++ allow `.name' operators to be redefined? Thanx, Paul mckenney@sri.com
morrison@eecs.nwu.edu (Vance Morrison) (03/18/88)
The question is "why doen't c++ allow you to overload the "." operator. I asked myself this very question and I don't have a good reason, but I did realise that the "." operator is fundamentally different from most other operators. Namely its right operand MUST BE A COMPILE TIME CONSTANT DEFINED FOR THAT PARTICULAR CLASS/STRUCTURE. I don't believe that this is the case with any other operator. In order for c++ to alow "mimicking" of this operator's semantics, (which is what all good overloaded operations do) there has to be a facility in c++ to access this compile time info. This opens up a whole new set of problems which are better thought out carefully first. The real reason you probably want overloading is to allow "controled access" to instance variables. What would meet this need without overloading the "." is for c++ to REDEFINE the "." operator for the class EXAMPLE so example.member means example.member() and if example.member() does not exist, then the "." means what it used to. I know for a fact that AT&T c++ does NOT allow member fuctions and member variables to have the same name so this would not break any code. SO HOW ABOUT IT?? Vance Morrison morrison@accuax.nmu.edu
gjditchfield@violet.waterloo.edu (Glen Ditchfield) (03/22/88)
In article <8180005@eecs.nwu.edu> morrison@eecs.nwu.edu (Vance Morrison) writes: > > The question is "why doen't c++ allow you to overload the "." operator. > > I asked myself this very question and I don't have a good reason, but >I did realise that the "." operator is fundamentally different from most >other operators. Namely its right operand MUST BE A COMPILE TIME CONSTANT >DEFINED FOR THAT PARTICULAR CLASS/STRUCTURE. You are treating "." as an infix operator whose right operand must come from some nameless, magical enumerated type. I think that the original writer meant that ".fieldName" would be treated as a postfix operator: "struct s { int a;};" might create a function named "s::operator .a". The field reference "anS.a" would be equivalent to "operator .a(anS)". Next problem: what is the returned type? "int& s::operator .a()" seems likely, since field a is normally an lvalue. But a is not an lvalue if the structure it is contained in is not an lvalue. Perhaps two friends are needed: "int& operator .a(s& someS)" and "int operator .a( (const s)& someS)". (Digression: I wish C++'s type system had a good way to express the concept of "lvalue". Reference types don't quite do it. I'd love to see discussion of the subtleties of this, under another subject heading.) Another problem is that "." functions are often proposed as a way of getting lvalue pseudo-members. A Trellis/Owl paper (in OOPSLA '86?) gives as an example a thermostat object whose setting is changed by assigning to the "Celsius" field or to the "Fahrenheit" field. The value assigned is treated as a temperature from the appropriate scale. One (or both) is a pseudo-member that scales the given temperature and sets other members. This won't work in C++, because assignment is an operator that is evaluated after its left operand. I haven't decided whether lvalue pseudo-members are good things or not. We can argue about that, too. Glen Ditchfield watmath!violet!gjditchfield Dept of Computer Science, U of Waterloo (519) 885-1211 x6658 Waterloo, Ontario, Canada Office: MC 2006 If you grab the bull by the horns, you at least confuse him -- R.A.Heinlein
mckenney@distek4..istc.sri.com (Paul E. McKenney) (03/22/88)
In article <8180005@eecs.nwu.edu> morrison@eecs.nwu.edu (Vance Morrison) writes: > The real reason you probably want overloading is to allow "controled >access" to instance variables. What would meet this need without overloading >the "." is for c++ to REDEFINE the "." operator for the class EXAMPLE so > example.member means example.member() > and if example.member() does not exist, then the "." means what it >used to. I know for a fact that AT&T c++ does NOT allow member fuctions >and member variables to have the same name so this would not break any >code. > SO HOW ABOUT IT?? > Vance Morrison > morrison@accuax.nmu.edu The only problem that I can see with this is if it is legal to pass member functions as parameters. The `C++ Programming Manual' claims that doing this is implementation-dependent (pg 276). I would have no problem stealing an implementation-dependent case, but I could imagine myself having a different attitude if I had written a large c++ application :-). If there is too much history out there to allow Vance's clever modification, perhaps the concept of `member operator' could be added to the current `member variable' and `member function' suite. For example, the declaration: struct s { int a { return (1) }; char b; } S; would declare these objects: o a structure `s'. o a postfix member operator `.a' that returns `int' when applied to an object of type `struct s'. o a postfix member operator `->a' that returns `int' when applied to an object of type `struct s *'. o a member variable `b' of type `char'. o a variable of type `struct s' named `S'. Then the compiler would decide which `.a' (or `->a') operator was to be invoked based on the type of the expression that it was applied to (just as for any other overloaded operator). Note that the declaration could be distinguished from member functions since there is no `()' after the name, and it could be distinguished from member variables because of the curly braces. This approach makes is unnecessary for the member operators to be in any way different from other operators. In particular, there is no need for any additional access to compile-time info, nor for any special compile-time constant requirements. Thanx, Paul
franka@mmintl.UUCP (Frank Adams) (03/22/88)
In article <8180005@eecs.nwu.edu> morrison@eecs.nwu.edu (Vance Morrison) writes: > The question is "why doen't c++ allow you to overload the "." operator. Actually, the original poster was regarding ".member" as the operator, not just the ".". > The real reason you probably want overloading is to allow "controled >access" to instance variables. What would meet this need without overloading >the "." is for c++ to REDEFINE the "." operator for the class EXAMPLE so > > example.member means example.member() The problem is that there are, more or less, two operations associated with members: access and update. The above is useless if I want to want to use statements like: "example.member = foo;". (It is *not* sufficient to define the member() function as returning a reference (such as "int &member()"), since in general, one wants to *do* something for the access/assignment.) -- Frank Adams ihnp4!philabs!pwa-b!mmintl!franka Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108
lsr@Apple.COM (Larry Rosenstein) (03/23/88)
In article <5868@watdragon.waterloo.edu> gjditchfield@violet.waterloo.edu (Glen Ditchfield) writes: > >Another problem is that "." functions are often proposed as a way of >getting lvalue pseudo-members. A Trellis/Owl paper (in OOPSLA '86?) >gives as an example a thermostat object whose setting is changed by >assigning to the "Celsius" field or to the "Fahrenheit" field. The value Trellis/Owl is based on CLU. In CLU the expression 'x.name' was syntactic sugar for the invocation 'typeof(x)$get_name(x)'. The assignment 'y.name := q' was sugar for the invocation 'typeof(y)$set_name(x, q)'. It seems as if C++ could use the same kind of mechanism. -- Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 32E Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr