lyj20080 发表于 2010-8-31 00:05:55

References vs. Pointers

Knowing how references really differ from pointers should help you decide when to use references and when to stick with pointers.

In C++, references provide many of the same capabilities as pointers. Although most C++ programmers seem to develop some intuition about when to use references instead of pointers, and vice versa, they still encounter situations where the choice isn't so clear. If you'd like to develop a reasonably consistent philosophy about using references, it really helps to know exactly how references differ from pointers. Those differences are my subject this month.


More than skin deep


A reference, like a pointer, is an object that you can use to refer indirectly to another object. A reference declaration has essentially the same syntactic structure as a pointer declaration. The difference is that while a pointer declaration uses the * operator, a reference declaration uses the & operator. For example, given:


int i = 3;


then:


int *pi = &i;


declares pi as an object of type "pointer to int" whose initial value is the address of object i. On the other hand:


int &ri = i;


declares ri as an object of type "reference to int" referring to i. The difference between pointer and reference declarations is noteworthy, but it's not the basis for deciding to use one over the other. The real basis for the choice is the difference in appearance between references and pointers when you use them in expressions.


The big difference between pointers and references is that you must use an explicit operator-the * operator-to dereference a pointer, but you don't use an operator to dereference a reference. For example, once the previous declarations are in place, the indirection expression *pi derefences pi to refer to i. In contrast, the expression ri-without any operators at all-dereferences ri to refer to i. Thus, an assignment such as: *p = 4;


changes the value of i to 4, as does the assignment:


ri = 4;


This difference in appearance is significant when you're choosing between pointers and references for function parameter types and return types. This is especially true in functions that declare overloaded operators.


In my first column on references, I illustrated this point with the example of defining a ++ operator for an enumeration type.1 In C++, the built-in ++ operator does not apply to enumerations. For example, given just:



enum day{Sunday, Monday, ...}; day x;

the expression ++x does not compile. If you want it to, you must define a function named operator++ which accepts a day as an argument.


Invoking ++x should change the value in x. Therefore, declaring operator++ with a parameter of type day, as in:


day operator++(day d);


won't have the desired effect. This function passes its argument by value, which means the function sees a copy of the argument, not the argument itself. For the function to alter the value of its operand, it must pass that operand either by a pointer or by a reference.


Passing the argument by a pointer, as in:


day *operator++(day *d);


would let the function alter the value of the day by storing the incremented value into *d. However, you would then invoke the operator using an expression such as ++&x, which doesn't look right.


The proper way to define operator++ is with a reference as the parameter type, as in:



day &operator++(day &d){d = (day)(d + 1);return d;}

Using this function, expressions such as ++x have the proper appearance as well as the proper behavior.


Passing by reference is not just the better way to write operator++, it's the only way. C++ doesn't really give you a choice here. A declaration such as:


day *operator++(day *d);
页: [1]
查看完整版本: References vs. Pointers