A pointer gives me the address of an object, ok. Nevertheless,
is
int * x_ptr;
the reverse of&
?: give it a pointer and it gives me an objectis
int & x_ref = y;
the reverse of*
?: give it an object and give me a pointer
A pointer gives me the address of an object, ok. Nevertheless,
is int * x_ptr;
the reverse of &
?: give it a pointer and it gives me an object
is int & x_ref = y;
the reverse of *
?: give it an object and give me a pointer
They are different types. The first (
int *
) is a pointer to an integer. The second (int &
) is an integer reference.Pointer.
Pointers point to objects, their value is a memory address. For practical purposes, they would be a data type that can only point to other objects; as an analogy they would be a postal code (which points to an urban area) or a vehicle registration (points to a vehicle) or a passport number (points to a person).
Lifecycle.
A pointer to a type
tipo *
can point to more than one object of typetipo
in its lifecycle, and can even point to no object at all or point to non-existent objects:Pointers are the only mechanism in C and C++ for managing dynamic memory; the operator
new
generates pointers on being called and transformation from array to pointer and vice versa is common practice.Modification of the targeted object.
With a pointer you can point to virtually any part of memory, which is why pointers are considered dangerous as well as useful; this flexibility of pointers can allow memory that does not belong to the running program to be examined or modified (for analysis or hacking ) which can cause program crashes.
Operations.
Arithmetic : Arithmetic operations can be performed with pointers: by adding a value to a pointer we obtain a pointer pointing to a memory area displaced from the original pointer as many bytes as the size of the pointed value:
By adding 1 to
puntero_char
, we will make the pointer point to the memory area 1 byte later than the area it originally pointed to (on systems thatchar
occupies one byte), subtracting 1 to willpuntero_int
make the pointer point to the memory area 4 bytes earlier to the zone it originally pointed to (on systems thatint
take up 4 bytes, or 32 bits). In both cases we will be pointing to memory that we should not be able to read or write, since both pointers were initialized to0
and the operating system usually prohibits access to the memory address0
(and various values close to0
).Address of : If we use the get-address operator on a pointer, we will add another level of pointer to the pointer, that is: the address of a pointer has type pointer to pointer, and the type of the address of the previous one would be pointer to pointer to pointer (and so on to infinity):
De-reference : If we use the de-reference operator on a pointer we will access the pointed object, allowing us to modify said object:
The example above makes it
valor
contain the value1
.Size : If we use the operator
sizeof
on a pointer, we will always get the same size regardless of the type pointed to, this size will vary depending on the system architecture; normally the size of the pointer matches the size of the processor word :Qualifiers.
A pointer can be qualified with
const
orvolatile
in four different ways:No qualifier : This is the qualification we have been looking at so far:
This mode allows you to target objects that lack qualifiers:
Qualify the targeted object : The qualification is applied on the targeted object:
This modality allows you to target objects with the same or lower qualification:
That is, with a pointer we can point to objects that are not qualified as if they were qualified with
const
orvolatile
.Qualify the pointer : The qualification is applied on the pointer:
Note that the qualifier is after the asterisk (
*
), in this case we are creating a constant pointer to a non-constant integer. Since the pointer is constant we cannot make it point to another object but we can modify the pointed object:Qualify both : The qualification is applied to both:
Notice that the qualifier is on both sides of the asterisk (
*
), in this case we are creating a constant pointer to a constant object. So we will not be able to modify the value of the object it points to or the object pointed to:As in previous cases, we see that the pointer can point to objects with less restrictive qualifications.
Reference.
References, reference objects, do not contain an address to the referenced object they are the referenced object. For all practical purposes a reference is indistinguishable from the object it references; as an analogy they would be a particle quantumly bonded with another.
Lifecycle.
A reference to a type
tipo &
only points to an object of typetipo
in its life cycle, which is why it is necessary to assign it at the time of its declaration:Modification of the targeted object.
References cannot change the object they reference, any assignment operation on a reference will modify the referenced object not the reference:
the statement
referencia = valor2;
does not make itreferencia
refer tovalor2
but assigns the value ofvalor2
to the object referenced byreferencia
, that is: itvalor1
will get the value2
.Operations.
Arithmetic : Since references only point to an object throughout its life cycle, it is not possible to do arithmetic operations to modify the referenced object; on the contrary, the operations performed on the reference will be applied to the referenced object, not to the reference itself, exactly the same as if the operation were performed on the referenced object:
The example above will cause it to
valor1
have the value2
noreferencia
pointing to the next oneint
in memory.Address of : It is not possible to obtain the memory address of a reference, on the contrary, the memory address obtained would be that of the referenced object:
De-reference : Using the de-reference operator on a reference will cause a compile error unless the referenced object accepts the operator:
Size : If we use the operator
sizeof
on a reference we will obtain the size of the referenced object:Qualifiers.
Since in practice a reference is the same object it references, it is only possible to reference objects with equal or lower qualifications. Unlike with pointers, it is not possible to qualify the reference only to the referenced object, so:
References without qualification : They can refer to objects without qualification:
References with qualification : They can reference objects with and without qualification:
int*
represents a pointer.int&
represents a reference.How do they look alike?
Internally we can consider that both elements are treated as pointers. That is, when making modifications you are altering the value of a third variable:
What is the difference between them?
The changes are several:
The reference doesn't give you the pointed memory address:
You cannot change the object pointed to by a reference:
It cannot be executed
delete
on a reference:In the references it is not necessary to use the indirection operator:
How do you know when to use each type?
References should be used when you don't need to access any of the features that make them different from pointers, since their use is much simpler and clearer than in the case of pointers.
For example, if a function returns a reference we can assume that we don't have to worry about clearing memory once we're done using the returned variable.