Comparison of the use of reference and pointers (pointer) in C + +

Source: Internet
Author: User
Tags bind comparison constant expression valid

Learn what the difference between reference reference and pointer pointer can help you decide when to use reference and when to use pointer.

In C + +, reference has the same ability in many ways as a pointer (pointer). While most C + + programmers have some intuition about when to use reference when using pointer, there will always be times when it is unclear. If you want to build a clear and rational concept of using reference, it's important to understand exactly what the difference is between reference and pointer.

Deep meaning

Similar to pointer, a reference is an object that can be used to point indirectly to another object. A reference statement is the same as the substantive grammatical structure of a pointer declaration. The difference is that the asterisk operator * is used when declaring pointer, and the address operator & is used when declaring reference. For example, we have:

int i = 3;

Then there are:

int *PI = &i;

An object that declares pi as a pointer type and is a "pointer to int integer" whose initial value is the address of object I. And on the other hand:

int &ri = i;

Declares that RI is an object of type reference and is also a reference that points to an integral type, which points to I. We can see that the statements made by pointer and reference are significantly different, but this is not the basis for deciding when to use them. The real rationale for decisions is that when they are used in an expression, the difference in their display determines which appropriate

Pointer and reference the biggest difference is: pointer must use an asterisk operator * to remove reference (English is called dereference, I do not know how to translate the word is appropriate, let's call "to refer to" bar) and reference does not need any operator to refer to. For example, with the definition in the above example, the indirect expression *pi the Pi to refer to the point I. In contrast, an expression ri-does not require any operator-automatically takes RI to refer to as pointing i. So, with the pointer p, we need to use the assignment statement:

*p = 4;

Change the value of I to 4; and using reference RI, we just need to write directly:

RI = 4;

You can also change the value of I to 4.

The difference in this display will be noticeable when you choose whether to use pointer or reference for the function's parameter type and return value type, especially for overloaded operator functions.

This is illustrated by an example of the + + operator for the enumeration type (enumeration) below. In C + +, the built-in + + operator is not valid for the enumeration type, for example, for the following definition:

Enum day{

Sunday, Monday, ...

};

Day x;

Expression ++x cannot be compiled. If you want it to compile, you must define a function named operator++, accept Day as a parameter, and call ++x must change the value of X. Therefore, only one function operator++ is declared, with the type day as the argument, as follows:

Day operator++ (day D);

Don't get the results you want. This function passes the parameter by value, which means that a copy of the parameter is seen within the function, not the parameter itself. In order for a function to change the value of its operand (operand), it must pass its operands through pointers or reference.

Passing parameters by pointer (passing by pointer), the function is defined as follows:

Day *operator++ (day *d);

It changes the value of the date (day) by storing the added value in *d. However, you must use the expression ++&x to invoke the operator, which does not seem to be a good thing.

The correct approach is to define operator++ to reference as the parameter type, as follows:

Day &operator++ (Day &d)

{

D = (day) (d + 1);

return D;

}

With this function, the expression ++x the correct display and the correct action.

Passing by reference is not just a good way to write operator++, but the only way. C + + Here does not give us a choice. Like the following statement:

Day *operator++ (day *d);

is not compiled. Each overloaded operator function must either be a member of a class, or use type T, T & or T const & as the parameter type, where T is a class (class) or enumeration (enumeration) type. That is, each overloaded operator must have a class or enumeration type as the parameter type. pointers, even pointers to a class or enumeration type object, are not available. C + + does not allow characters to redefine the meaning of built-in operators, including pointer types, in overloaded operations. Therefore, we can not define:

int operator++ (int i); Error

Because it attempts to redefine the meaning of operator + + for int. Nor can we define:

int *operator++ (int *i); Error

Because it attempts to redefine the meaning of operator + + for int *.

References vs. Const pointers

The definition of "const reference" is not allowed in C + + because a reference is inherently const. That is, once a reference is bound to an object, it is no longer possible to rebind it to another different object. After declaring a reference, you can rebind it to another object without writing it. For example:

int &ri = i;

Bind RI to I. And then the following assignment:

RI = j;

Instead of binding Ri to J, the value in J is assigned to the object that Ri points to, which is assigned to I.

In short, a pointer can point to many different objects in its lifetime, and a reference can only point to one object. Some people think this is the biggest difference between reference and pointer. I don't approve of it. Maybe this is a little different from the reference and pointer, but it's not the difference between reference and const pointer. Once again, once a reference is bound to an object, it cannot be changed to something else. Since it is no longer possible to bind reference and then change, a reference must be bound at birth. Otherwise this reference will never be bound to anything, and it will be useless.

The discussion of the previous paragraph is also fully applicable to constant pointers (const pointer). (Note that I'm talking about a constant pointer (const pointer) instead of a pointer to a constant "pointers to Const." For example, a reference declaration must also have an initialization assignment, as follows:

void F ()

{

int &r = i;

...

}

Omitting this initialization assignment will result in a compilation error:

void F ()

{

int &r; Error

...

}

The declaration of a constant pointer must also have an initialization assignment, as follows:

void F ()

{

int *const p = &i;

...

}

Omitting this initialization assignment also makes an error:

void F () {

int *const p; Error

...

}

In my opinion, it is not possible to reference two times binding as reference and pointer. is no more pronounced than the difference between a constant pointer and a very measured pointer.

Null references

In addition to the display, the constant pointer is very different from the reference, that is, a valid reference must point to an object, and a pointer does not need it. A pointer, even a constant pointer, can have null values. A null pointer does not point to anything.

This difference implies that when you want to make sure that a parameter must point to an object, you should use reference as the parameter type. For example, the SWAP function, which accepts two int parameters and swaps the values of two parameters, as follows:

int I, J;

Swap (I, j);

Place the value originally in I in J and place the value originally in J into I. We can write this function like this:

void swap (int *v1, int *v2)

{

int temp = *V1;

*V1 = *v2;

*v2 = temp;

}

In this definition, the function is called like this: Swap (&i, &j);

This interface implies that one or two of the parameters may be empty (null). And this hint is misleading. For example, call

Swap (&i, NULL);

The consequences are likely to be unpleasant.

Instead, define reference as a parameter as follows:

void swap (int &v1, int &v2)

{

int temp = V1;

V1 = v2;

v2 = temp;

}

It is clear that call swap should provide two objects, and their values will be exchanged. And another advantage of this definition is that when you call this function, you don't need to use those & symbols to look more pleasing:

Swap (I, j);

More secure?

Some people think that since reference cannot be empty, it should be more secure than the pointer. I think reference may be a little safer, but not much safer. Although a valid reference cannot be empty, it is invalid. In fact, in many cases the program may produce invalid reference, not just empty reference. For example, you can define a reference that binds to an object that the pointer points to, as follows:

int *p;

...

int &r = *p;

If the pointer *p is just empty when the reference is defined, the reference is empty. Technically, this error does not consist in binding reference to a null value, but in referring to a null pointer. A reference to a null pointer creates an indeterminate operation, which means that many things can happen and most of them are not good. It is quite possible that when the program binds reference R to the object *p (p), p is not actually referenced, and even the program simply copies the value of p to the pointer to implement R. And the program will continue to perform until the error is more evident in the running behind it, creating unpredictable hazards.

The following function shows another way to produce an invalid reference:

int &f ()

{

int i;

...

return i;

}

This function returns a reference that points to the local variable i. However, when the function returns, the storage space of the local variable I disappears. So this function actually returns a reference that points to the reclaimed space. This action is the same as the result of returning a pointer to a local variable. Some compilers can find this error at compile time, but it is very likely that it will not.

I like reference, and there are good reasons to use them instead of pointer. But if you expect to use reference to make your program more robust, you'll probably be disappointed.

Resources:

Saks, Dan. "Introduction to References," Embedded Systems Programming, January 2001, p. 81.

Saks, Dan. "References and const", Embedded Systems programming February 2001, p. 73.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.