References in C + +, pointers, references to pointers, pointers to pointers

Source: Internet
Author: User
Tags aliases

The three ways to define a pointer are: 1 int * p;  2. int* p; 3. int *p; The habit is different.
The three ways to define a function pointer are: 1. int *p (); 2. int * p (); 3. int* p ();

1. Pointer passing and reference passing

In C, if you want to implement a function that changes the value of an external variable, you should pass a pointer to the variable. If you want to access a variable through a pointer, you must use the pointer operator "*". In the source code will be more awkward:

void function (int *pval)
{
    *pval=100;
    PVAL=100, regardless of the type conversion error here, the code can only change the address of the temporary pointer variable in the stack, not the pointer to the object's value
}
int main ()
{
   int x=200; 
   function (&x);
   return 0;
}

In order to be able to use pointers transparently to access variables, C + + introduces the concept of "references"

void function (int &refval)
{
 refval=100
}
int main ()
{
 int x=200; 
 function (x);
 Of course, such as downward use also can. But doing so loses the original meaning of introducing a "quote"
 int &refx=x;
 function (REFX);
 return 0;
}

As a result, you can change the function declaration to achieve the consistency of pointer access and general access at the level of the source code. You can think of "reference" as a pointer to a variable without requiring a "*" operator. The C-language form of pseudocode for the above code:

void function (int *refal)
{
 *refval=100
}
int main ()
{
 int x=200;
 int *refx=&x;
 function (&x);
 function (REFX);
 return 0;
}

Summary:

Conceptually speaking. A pointer is essentially a variable that holds the address of a variable, logically independent, that can be changed, including the change in the address it points to and the data that is stored in the address to which it points.

Whereas a reference is an alias, it is logically not independent and its existence is dependent, so the reference must be initialized at the outset, and the object referenced by it cannot be changed throughout its lifecycle (it can only be attached to the same variable from beginning to end).

In C + +, pointers and references are often used for parameter passing of functions, however, pointer passing parameters and reference passing parameters are essentially different:

The pointer pass parameter is essentially the way the value is passed, and it passes an address value. In the process of value transfer, the formal parameters of the modulated function are treated as local variables of the modulated function, that is, the memory space is opened in the stack to hold the values of the arguments put in by the keynote function, thus becoming a copy of the argument. The characteristic of value transfer is that any operation of the function on the formal parameter is taken as a local variable and does not affect the value of the argument variable of the keynote function.

In the process of reference transfer, the formal parameters of the modulated function are also used as local variables to open up the memory space in the stack, but at this time is the address of the argument variable that is put in by the keynote function (when the pointer passes the parameter, the pointer holds the address of the argument, but the contents of the pointer stored within the function can be changed. That is, it is not safe to change the argument that is pointed, but the reference is different, and the address of the object that it refers to cannot be changed once it is given. Any operation of the called function on the formal parameter is treated as indirection, that is, the argument variable in the keynote function is accessed through the address stored in the stack. Because of this, any manipulation of the function on the formal parameter affects the argument variables in the keynote function.

Reference passing and pointer passing are different, although they are a local variable on the stack space of the called function, but any processing of reference parameters will be manipulated to the related variables in the keynote function through an indirection. And for the parameters passed by the pointer, if you change the pointer address in the called function, it will not affect the relevant variables of the key function. If you want to change the related variables in the keynote function by passing pointer arguments, you must use a pointer to the pointer, or a pointer reference. that the pointer pass is just a copy of the address, changing the address pointed to by the parameter inside the function can not change the address pointed to by the original argument, only by modifying the content of the formal parameter address, the purpose of modifying the content of the argument is achieved (the example of the original C language using the pointer to exchange the value of the small function), So if you want to modify the address of the original argument or reassign an object by a modified function, you can only use a two-pointer or pointer reference (detailed below).

To further deepen the distinction between pointers and references, let me elaborate on the differences between them from a compilation perspective:

The program adds pointers and references to the symbol table at compile time, where the variable name and the corresponding address of the variable are recorded on the symbol table. The corresponding address value of the pointer variable on the symbol table is the address value of the pointer variable, while the corresponding address value on the symbol table refers to the address value of the referenced object. The symbol table is not changed after it is built, so the pointer can change the object it points to (the value in the pointer variable can be changed), and the referenced object cannot be modified.

A further summary of the C + + symbol table: http://blog.csdn.net/cclive1601/article/details/8101313

Finally, summarize the similarities and differences between pointers and references:

★ The same point:

Are the concept of the address;

The pointer points to a piece of memory whose contents are the address of the memory, and the reference is an alias to a block of memory.

★ Different points:

The pointer is an entity and the reference is only an individual name;

References can only be initialized once at definition, then immutable, pointer variable, reference "one-woman", and pointers may be "inconstant";

The reference does not have a const, the pointer has a const,const pointer is immutable; (specifically, there is no int& const a form, and const int& A is, the former guidelines used in itself that alias can not change, of course, so do not need this form, the latter Guidelines can not be changed with the value indicated

The reference cannot be null, the pointer can be empty;

The "sizeof reference" gets the size of the variable (object) to which it is pointed, and the "sizeof pointer" gets the size of the pointer itself;

The value of the pointer and the reference of the self increment (+ +) operation is different;

References are type-safe, and pointers are not (references are more than pointer type checking

2. Pointers to pointers and references to pointers


In the following function declarations, why use both the * and & symbols. And what occasions use this declarative approach?
void Func1 (MYCLASS *&pbuildingelement);

First look at the "int **pp" and "int *&rp" difference. The former is a pointer to a pointer, and the latter is a reference to a pointer. If this is not clear, the change will be clear:

typedef int * LPINT;
Lpint *pp;
Lpint &rp; When the pointer and pointer references are passed as arguments, the compiler compiles the binary code to pass a double pointer when the following two functions are invoked, except that the invocation method of the two is different:

void function1 (int **p)
{
 **p=100;
 *p=null;
}
void function2 (int *&ref)
{
 *ref=100;
 Ref=null;
}

Visible, "Reference" is simply to provide the door to the overloaded operator, its essence and pointers are indistinguishable. So as long as you meet *&, you should think of * *. This means that the function modifies or may modify the caller's pointer, and the caller passes the pointer like a normal variable, without using the address operator &.

3, on the reference to the pointer to the following with three functions Onepointerfunc,poipointerfunc, refpointerfunc examples, three functions are to be called after the function can point to the new object.

Flyer pointer: Voidonepointerfunc (MYCLASS *pmyclass)

{
DoSomething (Pmyclass);
Pmyclass =//pointers to other objects
}

Call: myclass* p = new MYCLASS; Onepointerfunc (P); P does not point to new object after calling Onepointerfunc:
The second statement modifies only the value of the Pmyclass in the Function procedure. The value of the caller's variable p is not modified. If P points to an object at address 0x008a00, it still points to that particular object when the func1 returns.

Pass double pointer: voidpoipointerfunc (myclass** pmyclass);
{
*pmyclass = new MYCLASS;
}
Call: myclass* p =new MYCLASS; Poipointerfunc (&P); After calling Poipointerfunc, p points to the new object.

BTW, in COM programming, this usage is everywhere--for example, in the QueryInterface function of the query object interface:
Interface ISomeInterface {
HRESULT QueryInterface (IID &iid, void** ppvobj);
......
};
Lpsomeinterface P=null;
Pob->queryinterface (Iid_someinterface, &p);
Here, p is a pointer to the Someinterface type, so &p is the pointer to the pointer, and if the call succeeds when QueryInterface returns, then the variable p contains a pointer to the new interface.

Reference to pass pointer: Voidrefpointerfunc (MYCLASS *&pmyclass);
{
Pmyclass = new MYCLASS;
......
}

In fact, it is the same as the pointer to the previous example, but the syntax is different. Pass the time does not pass the address of P &p, but directly pass P itself:
Call: myclass* p = new MYCLASS;  Refpointerfunc (P); After calling Refpointerfunc, p points to the new object.


MFC uses the *& in its collection class as an example of a return modifier--coblist, which is a list of cobjects pointers.
Class Coblist:public CObject {
......
Gets/modifies the element at the specified location
cobject*& GetAt (POSITION POSITION);
cobject* GetAt (POSITION POSITION) const;
};
Here are two getat functions, which are the elements that get the given position. What's the difference. The difference is that one lets you modify the objects in the list, and the other is not. So if you write the following: cobject* pobj = mylist.  GetAt (POS); Then Pobj is a pointer to an object in the list.

If you then change the value of pobj: Pobj = psomeotherobj; This does not change the address of the object at the POS, but merely changes the variable pobj.


However, if written as follows: cobject*& rpobj = mylist. GetAt (POS);

Now, Rpobj is a pointer to an object in a list, so when you change the rpobj, it also changes the address of the object at the POS in the list--in other words, instead of the object. That's why CObList has two getat functions. One can modify the value of the pointer, and the other cannot. Notice what I'm saying here is the pointer, not the object itself. Both functions can modify the object, but only the *& version can override the object


4. Explanations of pointers and references

Pointer-a type t,t* is a pointer type that points to T, and a t* type variable can hold the address of a T object, and type T can add some qualifier, such as const, volatile, and so on. See the following figure, the meaning of the pointer:

Reference-Reference is an alias for an object, primarily for function arguments and return value types, and symbol x& represents a reference of type X. See the following figure, the meaning of the reference:

5. The difference between pointers and references first, the reference cannot be null, but the pointer can be empty. As mentioned earlier, references are aliases to objects, and references are empty--objects do not exist, and there can be aliases. So when you define a reference, you must initialize it. So if you have a variable that is used to point to another object, but it may be empty, you should use a pointer; If the variable always points to an object, i.e. your design does not allow the variable to be empty, you should use a reference. In the following illustration, if you define a reference variable, you cannot even compile without initializing it (compile-time error):

A declaration pointer can be without pointing at any object, and for that reason, you must do a null-and-void operation before using the pointer, and the reference is not necessary . Second, a reference cannot change the point of "Death to death" on an object, but the pointer can change points and point to other objects. Note: Although references may not change the point, you can change the contents of the initialization object. For example, for the + + operation, the operation of the reference directly reacts to the object being pointed to, rather than changing the point, and the action on the pointer causes the pointer to point to the next object instead of changing the contents of the object being referred to. See the following code:

#include <iostream>

using namespace std;

int main (int argc,char** argv)
{

    int i=10;
    int& ref=i;
    ref++;
    cout<< "i=" <<i<<endl;
    cout<< "ref=" <<ref<<endl;

    int j=20;
    Ref=j;
    ref++;
    cout<< "i=" <<i<<endl;
    cout<< "ref=" <<ref<<endl;
    cout<< "j=" <<j<<endl;
    return 0;
}

The + + operation of ref is a direct reaction to the indicated variable, re-assign "Ref=j" To reference variable ref (note here that ref can be assigned again, but the point does not change) and does not change the direction of ref, it still points to I instead of J. Of course, the + + operation on ref does not affect J. These changes are pointers, the situation is very different, please experiment. The output results are as follows:

Again, the size of the reference is the size of the variable being pointed to, because the reference is only an alias; the pointer is the size of the pointer itself, 4 bytes. As shown in the following figure:

As you can see from the above , references are more formal than pointers, and using references to content can be used to refer to variable names instead of using * when you define references, and you don't need to use a & address like a pointer. Finally, the reference is more secure than the pointer. Because a null reference does not exist, and once the 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 be either uninitialized or null, so it is unsafe. The const pointer cannot change the point, but there is still a null pointer, and it is possible to produce wild pointers (that is, multiple pointers point to a piece of memory, and after a pointer is dropped, the other pointers become wild pointers).

All in all, words and all--their differences can all boil down to "a pointer to a piece of memory, its content is the address of the memory, and a reference is the alias of a block of memory, the reference does not change the point." " 6, the special const

Why do I mention the const keyword here? Because there is a difference between const's limitations on pointers and references, listen to me below

Related Article

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.