Welcome: Hunan Intelligent Applications Tecgnology CO.,ltd.-HNIAT.com
Language: Chinese ∷  English

Basic knowledge

The difference between C ++ pointers and references

The difference between C ++ pointers and references

Category Tags: C ++


       Pointers and references are very different in form, but they seem to have the same function, and they can directly reference objects and perform direct operations on them. But when do you use pointers? When to use references? The two are easy to confuse. Here I introduce pointers and references in detail, and strive to show you the most real side. If I do n’t spray well enough, I hope to be merciful under my mouth and stay alive, please give me some pointers. If you feel good, please applaud.

       1, the definition of pointers and references

       Before going into the in-depth introduction, let's first look at the definition of pointers and references, the differences between pointers and references, and then discuss the pointers and references respectively. Let's go into the details of these differences.

       ● Authoritative definition of pointers:


In a declaration T D where D has the form

* cv-qualifier-seqopt D1

And the type of the identifier in the declaration T D1 is "derived-declarator-type-list T", then the type of the identifier of D is "derived-declarator-type-list cv-qualifier-seq pointer to T". The cv-qualifiers apply to the pointer and not to the object pointer to.

——From "ANSI C ++ Standard"

       Note: Some readers may not understand cv-qualifier-seq

       CV-qualifiers

       There are three types of CV-qualifiers: const-qualifier (const qualifier), volatile-qualifier (volatile qualifier), and const-volatile-qualifier (const-volatile qualifier).

       Non-static, non-mutable, and non-reference data members of const class objects are const-qualified;

       Non-static, non-reference data members of volatile class objects are volatile-qualified;

       Non-static, non-reference data members of const-volatile class objects are const-volatile-qualified.

       When CV-qualifiers are used to qualify an array type, the array members are actually qualified by the CV-qualifiers, not the array type.

       A composite type is not qualified by the CV-qualifier because its members are qualified by the CV-qualifier, that is, even if the members of the composite type are CV-qualifier qualified, the composite type is not a CV-qualified object.

       ● Authoritative definitions cited:


In a declaration T D where D has the form

& D1

And the type of the identifier in the declaration T D1 is "derived-declarator-type-list T", then the type of the identifier of D is "derived-declarator-type-list cv-qualifier-seq reference to T". Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef or a template type argument, in which case the cv-qualifiers are ignored.

——From "ANSI C ++ Standard"

       The definitions above are a bit difficult to understand at first. If this is the case, it means that you are not familiar with C ++, and you still have a long way to go. Here's an overview in plain words:

       ● Pointer-For a type T, T * is a pointer type to T, that is, a variable of type T * can hold the address of a T object, and type T can be added with some qualifiers, such as const, volatile, etc. . See the figure below for the meaning of the pointers shown:

The difference between C ++ pointers and references

       ● Reference-A reference is an alias of an object and is mainly used for function parameters and return value types. The symbol X & refers to an X type reference. See the figure below for the meaning of the references shown:

The difference between C ++ pointers and references

       The difference between pointers and references

       ● First, references cannot be null, but pointers can be null. As mentioned earlier, references are aliases of objects, and references are empty-objects do not exist, how can there be aliases! Therefore, when defining a reference, it must be initialized. So if you have a variable that points to another object, but it may be empty, you should use a pointer; if the variable always points to an object, ie, your design does not allow the variable to be empty, then you should Use references. As shown in the figure below, if you define a reference variable, you can't even compile it without initializing it (compile-time error):

The difference between C ++ pointers and references

       ● You can declare a pointer without pointing to any object. It is for this reason that you must perform a null operation before using a pointer, and you do not need a reference.

       ● Secondly, references cannot change the pointing, "to the end" of an object; but pointers can change the pointing and point to other objects. Note: Although the reference cannot change the direction, the content of the initialization object can be changed. For example, as far as the ++ operation is concerned, the operation of the reference directly reflects the pointed object, instead of changing the pointing; and the operation of the pointer makes the pointer point to the next object, instead of changing the content of the pointed object. See the following code:


C ++ code
1. # include <iostream>
2.using namespace std;
3.
4.int main (int argc, char ** argv)
5. {
6.int i = 10;
7.int & ref = i;
8.ref ++;
9.  
10.cout << "i =" << i << endl;
11.cout << "ref =" << ref << endl;
12.
13.int j = 20;
14.ref = j;
15.ref ++;
16.
17.cout << "i =" << i << endl;
18.cout << "ref =" << ref << endl;
19.cout << "j =" << j << endl;
20.return 0;
twenty one.}  

       The ++ operation on ref is directly reflected on the referenced variable. Reassigning "ref = j" to the reference variable ref does not change the reference of ref. It still points to i, not j. Of course, the ++ operation on ref will not affect j at this time. When these are used as pointers, the situation is very different, please experiment by yourself. The output is as follows:

The difference between C ++ pointers and references

       ● Again, the size of the reference is the size of the variable pointed to because the reference is just an alias; the pointer is the size of the pointer itself, 4 bytes. See the figure below:

The difference between C ++ pointers and references

       ● It can also be seen from the above that references are more beautiful in form than pointers. You can use reference variable names between the content pointed to by references, instead of using pointers like pointers; and you do n’t need to use pointers when defining references Use & Addressing.

       ● Finally, references are more secure than pointers. Because there is no null reference, and once a reference is initialized to point to an object, it cannot be changed to a reference to another object, so the reference is safe. For pointers, it can point to other objects at any time, and can not be initialized or NULL, so it is not safe. Although the const pointer cannot change the pointer, there are still null pointers, and wild pointers may be generated (that is, multiple pointers point to a piece of memory. After one pointer is freed, other pointers become wild pointers).

       All in all, in short-these differences can be attributed to "pointers point to a piece of memory, whose content is the address of the pointed memory; references are aliases of a block of memory, and references do not change the pointer."

       3.What's special about const

       Why should I mention the const keyword here? Because const's restrictions on pointers and references are different, let me hear them one by one.

       ● Constant pointer vs constant reference

       Constant pointer: A pointer to a constant. Add const before the type of the pointer definition statement to indicate that the object pointed to is a constant.

       Defining a pointer to a constant only restricts the indirect access operation of the pointer, and cannot specify the operation prescriptiveness of the value pointed to by the pointer itself.

The difference between C ++ pointers and references

       The constant pointer definition "const int * pointer = & a" tells the compiler that * pointer is a constant and cannot operate on * pointer as an lvalue.

       Constant reference: A reference to a constant. Add const before the type of the reference definition statement to indicate that the object pointed to is a constant. Like pointers, you cannot use references to reassign the variable pointed to.

The difference between C ++ pointers and references

       ● Pointer constants vs. reference constants

       Add const before the pointer name of the pointer definition statement to indicate that the pointer itself is a constant. Must be initialized when defining pointer constants! And this is a property that is born by reference. You don't need to add const before the reference name of the pointer definition statement.

       The pointer constant definition "int * const pointer = & b" tells the compiler that pointer is a constant and cannot be manipulated as an lvalue, but allows modification of indirect access values, that is, * pointer can be modified.

The difference between C ++ pointers and references

       ● Constant pointer constant vs constant reference constant

       Constant pointer constant: A pointer constant that points to a constant. You can define a pointer constant that points to a constant. It must be initialized when it is defined. The constant pointer constant definition "const int * const pointer = & c" tells the compiler that pointer and * pointer are both constants, and they cannot be operated on as lvalues.

       There is no such thing as "constant reference constant", because referencing a variable as mentioned above is referencing a constant. C ++ does not distinguish between const references to variables and const variables. A program must never reassign a reference to itself, so that it points to another variable, so the reference is always const. If you apply the keyword const to a reference, it works by making its target a const variable. That is not: Const double const & a = 1; only const double & a = 1;

       In summary: there is a rule that can distinguish between const and the data pointed by the pointer—draw an asterisk (*) declared vertically across the pointer. If const appears to the left of the line, the data pointed by the pointer is constant ; If const appears on the right, the pointer itself is constant. References are inherently constants, which means that you cannot change the direction.

       4, the implementation of pointers and references

       We use the following simple code to analyze pointers and references in depth:


C ++ code
1. # include <iostream>
2.using namespace std;
3.
4.int main (int argc, char ** argv)
5. {
6.int i = 1;
7.int & ref = i;
8.int x = ref;
9.  
10.cout << "x is" << x << endl;
11.
12.ref = 2;
13.int * p = & i;
14.
15.cout << "ref =" << ref << ", i =" << i << endl;
16.}

       After the above code is compiled with g ++ test.c, and then disassemble objdump -d a.out, a piece of assembly code for the main function is as follows:


C ++ code
1.08048714 <main>:
2.8048714: 55 push% ebp
3.8048715: 89 e5 mov% esp,% ebp
4.8048717: 83 e4 f0 and $ 0xfffffff0,% esp // are the arguments argc and a of the main function

CONTACT US

Contact: Manager Xu

Phone: 13907330718

Tel: 0731-22222718

Email: hniatcom@163.com

Add: Room 603, 6th Floor, Shifting Room, No. 2, Orbit Zhigu, No. 79 Liancheng Road, Shifeng District, Zhuzhou City, Hunan Province

Scan the qr codeClose
the qr code