References and pointers
References and pointers have an interesting relationship — a reference acts like a const pointer that is implicitly dereferenced. Thus given the following:
1
2
3
|
int nValue = 5;
int * const pnValue = &nValue;
int &rnValue = nValue;
|
*pnValue
and rnValue
evaluate identically. As a result, the following two statements produce the same effect:
1
2
|
*pnValue = 6;
rnValue = 6;
|
Similarly, a const reference acts just like a const pointer to a const object that is implicitly dereferenced.
Because references always “point” to valid objects, and can never be pointed to deallocated memory, references are safer to use than pointers. If a task can be solved with either a reference or a pointer, the reference should generally be preferred. Pointers should generally only be used in situations where references are not sufficient (such as dynamically allocating memory).
Member selection
It is common to have either a pointer or a reference to a struct (or class). As you learned previously, you can select the member of a struct using the member selection operator (.):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
struct Something
{
int nValue;
float fValue;
};
Something sSomething;
sSomething.nValue = 5;
Something &rsSomething = sSomething;
rsSomething.nValue = 5;
Something *psSomething = &sSomething;
(*psSomething).nValue = 5;
|
Note that the pointer dereference must be enclosed in parenthesis, because the member selection operator has a higher precedence than the dereference operator.
Because the syntax for access to structs and class members through a pointer is awkward, C++ offers a second member selection operator (->) for doing member selection from pointers. The following two lines are equivalent:
1
2
|
(*psSomething).nValue = 5;
psSomething->nValue = 5;
|
This is not only easier to type, but is also much less prone to error because there are no precedence issues to worry about. Consequently, when doing member access through a pointer, always use the -> operator.
0 comments: