Thread: [Dev-C++] A Question of & use
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: Roger F. <ra...@ha...> - 2004-08-25 04:46:32
|
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
|
|
From: Per W. <pw...@ia...> - 2004-08-25 06:49:54
|
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
>
|
|
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
>
|