|
From: Per W. <pw...@ia...> - 2004-08-25 07:33:55
|
Just a footnote. lhs and rhs are not common expressions. Most computer
language books talks about l-val and r-val for left-hand and right-hand
expressions.
/Per W
On Wed, 25 Aug 2004, Per Westermark wrote:
> First of all, a reference is just a special case of a pointer. The
> "special" is that you must assign an address to it by specifying another
> variable for it to reference.
>
> Second "special" is that you can not change what a reference variable
> points to, while a pointer may be modified any number of times.
>
> Third "special" is that you don't use the normal pointer indirection code,
> i.e. p->xx or *p when using a reference variable, but may use it directly
> as in: ref.xx or just ref.
>
>
> When you declare a variable as a reference type, the & binds to the
> variable/parameter name, not to the type. This sarts to make sense when
> you declare more than one variable, as in:
>
> // Create two integer variables, and give them values.
> int a = 10,b=12;
>
> // Now create two reference variables pointing at a and b
> int &my_ref_a = a,&my_ref_b = b;
>
> // Now it is possible to change the value of b by:
> my_ref_b = 100;
>
> // Emit new value (100).
> std::cout << b << std::endl;
>
> If & hand bound to the type instead, the above variable declarations
> would have looked like:
> int& my_ref_var1 = a,my_ref_var2 = b;
> i.e. you would only have needed _one_ & while declaring two variables of
> type reference to integer. Observe however, that the above does something
> completely different from the first line. Since & binds to the variable,
> my_ref_var1 has a & before it, and is a reference to an integer variable
> (a), while my_ref_var2 _doesn't_ have a & before, so it is just an integer
> variable getting a copy of the value of variable b, i.e. later assign to
> my_ref_b will not change the value of b.
>
> It is the same for pointer types, i.e. when creating pointer variables to
> int, each individual pointer variable needs it's own *, since * isn't
> bound to the int type:
>
> int *ptr1,*ptr2,*ptr3;
>
> In your examples, i.e. when specifying a parameter of reference type, it
> isn't obvious reference (or pointer) binds to left or right (to type or
> variable), since each parameter must have it's own type declaration:
> void fnk(int &a,int &b) {}
> where the following is invalid because b doesn't have a type specified:
> void fnk(int &a,&b) {}
>
> Your question about line 8 isn't so strange. When declaring a function
> prototype (or operator prototype), you might skip writing the parameter
> name, as in:
>
> int my_function(int &);
>
> int my_function(int &ref_param) {
> return ++ref_param;
> }
>
> but
> int my_function(int &);
> (your line 8) is identical to
> int my_funcion(int&);
> since white-space doesn't matter, or
> int my_function(int &one_parameter_name);
> since existence of parameter names doesn't matter in a function prototype,
> only the type of the parameters.
>
>
>
> Once more:
> int my_function(int &);
> _doesn't_ have the & last, since there is an "invisible" :) parameter name
> following it. It is just a lazy short-form of declaration.
>
>
>
> lhs/rhs is indeed left-hand-side and right-hand-side and is important in
> assignment operations.
> lhs = rhs;
> where lhs may not be a const variable since the assignment will try to
> change the value of lhs.
>
> Another example where rhs and rhs are important is when & is used as
> address-of operator (instead of a delcaration of a reference variable). It
> isn't possible to change the address of a variable. If it is global/auto,
> it has a fixed address and if it is a dynamically allocated variable the
> address is set by new/malloc.
>
> int a = 10,b = 12;
>
> a = b; // OK. a now set to 12
> &a = &b; // NOT OK. Can't _move_ a.
>
> int *pa = &a; *pb = &b;
> *pa = b; // OK. pa points to a, so a gets set to value of b.
> pa = &b; // OK. pa now points to b instead of pointing to a.
>
> int &refa = a,&refb = b;
> refa = b; // OK. a now set to 12.
> refa = refb; // OK. a now set to 12.
>
>
>
> One special thing to think about is that a reference may only be set once.
> If the referene variable is a member of a class, it must be set by the
> constructor, i.e.
>
> class MyClass {
> int &m_ref;
> public:
> MyClass(int ¶m) : m_ref(param) {}
> setval(int v) { m_ref = v; }
> }
>
> int main() {
> int a = 10;
> MyClass mc(a);
>
> mc.setval(12); // a now changed to value 12
> }
>
>
> If the reference variable is global or auto, it must be assigned
> immediately in the declaration, i.e.
> int a;
> int &aref = a; // Let aref reference (or point to) a
> int &aref2; // Invalid - can't have uninitialized references!
>
> /Per W
>
> On Tue, 24 Aug 2004, Roger Furer wrote:
>
> > Aloha from Honolulu,
> > I've been learning C++ using "Sam's Teach Yourself C++" and when I
> > came across "Effective C++ Second Edition" in a used-book store, I
> > picked it up (both books mention each other). My reference book had
> > been "Turbo C/C++ The Complete Reference (Second Edition)" which was
> > copyright 1992 (I was using Windows 3.1 and Borland's Turbo C++ 3).
> > Finding the reference to be so out-of-date, I bought a new one: "The
> > Complete Reference C++ Fourth Edition". This has a 2003 copyright and
> > is much more up-to-date. I find it very useful when looking up
> > specifics of things mentioned in the first two books.
> >
> > My questions for the group have to do with using the ampersand (&)
> > for references.
> >
> > First: in "Effective C++", item 15, p. 65:
> > "operator= default version C& C::operator=(const C&);"
> > The & follows the variable (?).
> >
> > But in "The Complete Reference" on p. 347 the author states
> > "... as specified in the C++ syntax, when used in a
> > declaration, the * (or &) is linked to the individual variable that it
> > _/precedes/_, (my emphasis) not to the type that it follows."
> >
> > Second: In both "Sam's Teach Yourself..." and "Effective C++" the
> > authors use "rhs" and "lhs" throughout.
> > Example from "Teach Yourself C++" p.203: defining a class called
> > "CAT" the following is the declaration for the copy constructor on line 8:
> > 8: CAT (const CAT &); // copy constructor
> > Later on line 27 it is defined:
> > 27: CAT::CAT(const CAT & rhs)
> > 28: { ... the definition continues...
> >
> > The author makes it clear that "rhs" stands for "right hand side" and
> > "lhs" for "left hand side" and from the way they use them I have a
> > pretty good idea of what they mean, but I can find no mention of either
> > one in "The Complete Reference" and nowhere is there anything like line
> > 8 above: (const CAT &) where the & is at the end.
> >
> > Can anyone clear this up for me?
> >
> > Much thanks in advance.
> > Mahalo,
> > Roger
> >
> >
> >
> >
> > -------------------------------------------------------
> > SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
> > 100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
> > Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
> > http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285
> > _______________________________________________
> > Dev-cpp-users mailing list
> > Dev...@li...
> > TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
> >
>
>
>
> -------------------------------------------------------
> SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
> 100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
> Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
> http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|