What are the differences between pointer and reference in c++?

Asked

Viewed 2,490 times

8

This question is a specific version for c++ of the question: What is the difference between pointer and reference?

In practice, what are the differences between a pointer and a reference in C++?

I say in practice because I would not like purely descriptive and sometimes ambiguous answers, such as some in Soen’s question. What I am looking for are practical illustrations of these differences, which in addition to the explanation contain simple and point-to-point examples of codes.

3 answers

3

  • references in si (not the referenced type), are always const, therefore always initialized once, pointers not.

It may be difficult to imagine an attempt to reset a reference, since after the initial boot where the bind with a variable, the following attributes will always treat the reference as an alias for the original variable, not an attempt to do rebind There is another variable. But it is possible to replicate this when dealing with references indirectly, forcing the situation of rebind, example:

struct S {
    int &x;
};

int main() {
    int a = 0, b = 0;
    S s1{ a }, s2 { b };

    s2 = s1;

    // Clang Error:
    //
    // refs.cpp:9:8: error: object of type 'S' cannot be assigned because its
    //                      copy assignment operator is implicitly deleted
    //     s2 = s1;
    //        ^
    // refs.cpp:2:10: note: copy assignment operator of 'S' is implicitly
    //                      deleted because field 'x' is of reference type
    //                      'int &'
    //     int &x;
    //          ^
    // 1 error generated.
}

s1 and s2 are two simple objects of the type S that has a reference member. I build them by having members reference two different variables.

When I try to make a trivial attribution, which is only a mere memory copy (which in theory would be a means of bypassing the system to get a rebind of the internal reference, leaving the two referencing the same variable, since s1 and s2 would equal bit-a-bit) the compiler does not allow.

This same type of error would occur if the member were a const int x or int * const x, as variables cannot be reset const.

Bonus

C++ has pointers and references, Java, as many people say, "passes objects by reference". Actually no, actually Java has pointers, and everything goes by value, including the pointers, erroneously treated as reference.

  • I still don’t understand what you meant by the first point. It’s like you don’t exist int& var = var2; var = 1;

  • @Lucashenrique this you did is a change in the referenced value, not a reference rivend to another variable.

  • @Lucashenrique pointers can be int *var or const int *var or int * const var or const int * const var. One thing is the pointed type being constant, another the variable itself.

  • Ah. That’s really right. It’s just a little ambiguous. I think it would be better if you put "references in themselves, that is, the memory block to which it points [...]"

  • @Lucashenrique is precisely "the block of memory to which she points" that may or may not be const, she herself is not, is always const. It would be wrong.

  • Pepper, it wouldn’t be possible to put code examples for each of the dots?

  • 1

    @Carloscinelli Yes, I just don’t have time now. It’s later.

  • Java did not use the term reference before C++?

  • @Pablo believes not, c++ exists before the existence of java, and "reference" actually gives name to an element of the syntax of c++, different from the use of this term in java for example. Nevertheless, it is worth reading the article I passed about, which proves that java actually has a kind of restricted pointer, these are usually treated as "reference" in a certain way erroneous.

Show 5 more comments

1

References play a role similar to a pointer, but the address to which it refers is immutable. When you touch a reference, you’re not doing anything but tinkering with the variable it refers to, it never changes. They are equivalent, but should be used according to the cases in which they are requested, performing their core functions. There is also a specific type of references that behave differently, called tree reference. It is used when the life time of variable is small.


What also changes is the way the compiler will treat the variable you have, syntactic sugar and good practices. This is very general, this way, so let’s look at an example. If you have a function int f(int&), you can enter both with a int& or with a *(int*), correct - in these cases, they necessarily complement each other. Because this is the basic, a concept that arose from C to C++. If you’re going to look at the most common Windows or Linux Apis, you’ll notice that variables that change are always passed by pointers, since in C there were no references. They created these references to make the program safer and "beautiful" because, after all, pointers are one of the most "unpredictable" things about programming errors.

If you know Assembly, the difference of a pointer is that (analogously, not literally) when you call a mnemonic or perform a function, it performs MNM var, and with a reference, MNM [var]. This is to say that C++ mostly treats references as dereferenced pointers, pointers as references to a variable, and vice versa. They are similar, but different in practice, as the example of function. In practice, when you have a data string in memory, ask for a pointer. If you need a variable to alter in memory, ask for a reference. The cleaner a code is, the less likely it is to be wrong.


Example:

void f(int&&);
int main()
{
    int var;
    int& referencia = var;
    referencia = 1; // o valor de var agora é 1
    std::cout << (int)&referencia; //imprime o endereço em que var se encontra, dando o ponteiro para a variável
    &referencia = (int*)0; // ERRO: imutável
    f(1); //imprime 1, valor literal
    f(referencia); // ERRO
}

void f(int&& var)
{
    std::cout << var;
}

0

A reference is "secure": it cannot be null and the compiler ensures that it points to a valid object. You cannot simply declare a variable

Objeto &x;

because then the variable would be null or invalid. The statement needs to include the definition:

Objeto y = Objeto();
Objeto &x = y;          // x e y são o mesmo objeto

In a class, you can declare a member to be a reference, but you need to use the "member startup list" syntax to ensure that the member is already valid when the constructor body starts running:

class Bla {
   Objeto &x;
   Bla(Objeto &param): x(param) {
       ... 
   }
};

Note that in order to start member x, a reference to Object had to be sent as a parameter to the constructor, because a valid reference has to go from somewhere, it does not materialize from nothing.

References to objects, as well as pointers to objects, allow the use of polymorphism. If Otherobject is a subclass of Object, the following syntax is valid:

OutroObjeto y = OutroObjeto();
Objeto &x = y;

Pointers can be null (which is sometimes an advantage), may point to objects that have already been released from memory, and may even point to arbitrary memory positions, upon unsafe Caps.

If there is no specific reason to use pointers and/or objects allocated with new, it is always best to use references to objects created on a stack.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.