[Reposted from http://blog.csdn.net/zengwke/archive/2008/05/16/2452735.aspx]
Before reading this article, you must first understand that the various access control that c ++ provides for us is only a limitation given to us during the compilation phase, that is to say, the compiler ensures the correct behavior before you complete the task. If your behavior is incorrect, you can't create any executable programs. However, if we are in the stage of producing executable code, whether it is c, c ++, or pascal, everyone is the same, do you think the machine code produced by c and c ++ compilers will be different? Do you think the machine code produced by c ++ has access restrictions? So you are wrong. No const or private (the const variable may be placed in the read-only data segment). It will not impose any restrictions on you, you can use all the memory modification tools or write a program to modify a variable in a process space, whether it is private or public in your impression, at this time, you are all the same. In addition, you should not be amazed by the late bundling mechanism provided by c ++. It just adds a few more lines to the generated code, it is far less intelligent than you think. All the work is done by the compiler. When it comes to execution, the computer will execute the code exactly according to the compiler. Do you understand what I'm talking about? By the way, if you have been in touch with Assembly before, as long as you disassemble a piece of c ++ code, you will say: this is the case, c ++ only abstracts our problems at a higher level. However, as long as you unlock the veil and return to the source of the problem, everything will no longer be mysterious ......
(The following disassembly code is from visial c ++ 7.0)
1. Let's start with the variable. It's not as simple as you think.
What is a variable? A variable is a variable that can be changed during program execution. From another perspective, a variable is the name of a memory area, which represents the memory area. When we modify the variable, the content in the memory area will change. However, if you have learned the assembly or computer composition principle, you will know that there is no name for a memory area, and all its symbols are its addresses, therefore, if you want to modify the content of a memory area, you only need to know its address. It seems that the so-called variables are just an abstraction provided by the compiler, so that we do not have to know more details and reduce our thinking span. For example, the following statement:
Int a = 10;
According to our habits of thinking, there is a variable a with a value of 10. Everything looks so natural. We don't have to care about the so-called addresses and other details. However, in the underlying implementation of this statement, a is no longer a variable. It is just a tag that represents an address:
Mov dword ptr [a], 0Ah;
This statement is not as easy to accept as the one above, because it requires more details and you can hardly get any help from the compiler, you must do everything you think about. This statement should be interpreted as "writing 10 to the memory region with a address ". What do you mean? A is somewhat like a pointer? Yes, it does, but it does not, but their process seems similar. The bridge mentioned here is actually a bridge from a real problem to a specific address and a memory area.
2. Reference: You can have references, but the compiler only has pointers (addresses)
After reading the first article, you must have a certain understanding of the compiler work. In fact, the compiler is a conversion layer between the programmer and the underlying layer. It converts a high-level language code into a low-level language code, the larger the conversion span of a compiler, the more complicated it will be, because the programmer's work is done by him. The C ++ compiler must be more complex than the assembly compiler. If I ask you if the reference is the same as the pointer? You may say that, of course, it is different. Pointers are prone to insecure factors, but references are not. Is it true? Let's look at the following code:
Int * e = new int (10 );
Int & f = * e;
Delete e;
F = 30;
What do you think of the above Code? I don't feel very secure. It has the same risks as pointers. Because the memory region it references is invalid.
I personally think that the so-called reference is actually a pointer, but the interfaces of the two are not the same, and the referenced interfaces have certain restrictions. The pointer can be one-to-many, but the reference can only be one-to-one. That is, & refer cannot be changed, but it cannot be said that one-to-one is safe, but the dangerous coefficient is reduced. References are easier to control than pointers.
OK. Let's talk about pointers. People who have had assembly experience will say, well, some points of pointers are like assemblies, especially those "*". how is it like "[]" in the assembly. Haha, indeed, it also covers an addressing process. It seems that the pointer is indeed a relatively low-level thing. However, the reference is not so direct, although programmers are much more convenient and secure to use. But you need to be clear that only you can have references, the compiler does not have this tool, and the computer does not know it. Therefore, its underlying mechanism is actually the same as the pointer. Do not believe that there is only one copy of the memory. Do not think that the reference can save a pointer space for you, because this will not happen, and the compiler will still interpret the reference as a pointer. Whether you believe it or not, please refer to the following code:
Int & B =;
Lea eax, [a];
Mov dword ptr [B], eax; assigns the address of a to a piece of memory of B.
B = 50;
Mov eax, dword ptr [B];
Mov dword ptr [eax], 32 h;
Int * d = &;
Lea eax, [a];
Mov dword ptr [d], eax
* D = 60;
Mov eax, dword ptr [d]
Mov dword ptr [eax], 3ch;
The above Code comes from a specific compiler. How about it? Believe it. Well, let me make another comparison that may not be very appropriate. You must have compiled a program related to linear tables and stacks, A linear table is a flexible data structure with many operations on it. However, as a stack, It is a linear table with restrictive operations. Its underlying operations are actually implemented by linear table operations. It is like the relationship between stack and vector. Therefore, the relationship between pointer and reference is like the relationship between linear table and stack. Reference is a restricted pointer. Although its external interfaces and pointers are not the same, however, the underlying layer is the same.
Next, let's take a look at an important purpose of reference. What is the situation when it is passed as a function parameter:
Void swapr (int & a, int & B );
Void swapr (int * a, int * B );
Int a = 10;
Int B = 20;
Swapr (a, B );
Lea eax, [a];
Push eax; // push the address of a to the stack.
Lea ecx, [B];
Push ecx;
Call swapr;
Swapr (& a, & B );
Lea eax, [a];
Push eax;
Lea ecx, [B];
Push ecx;
Call swapr;
How about transferring parameters with references and pointers is the same in terms of efficiency and space. If you want to modify the value of the real parameter without passing in the address, it's just a fantasy, this shows that the essence of reference is pointer. After all, their behavior is too similar. If not, do you have any methods to implement reference? Remember, references are just a useful and secure tool provided by the compiler. For machine code, you cannot express them. It removes the one-to-many disadvantages of pointers, your insecure operations are prohibited. But back to the source of the problem, there is no difference between them.