Question

I am having trouble understanding when to use & with a variable. I think it changes the scope to that function but for some reason this code isn't working

void advanceTimeInMinutes(int& hours, int& minutes, int& advances)
{
    if(advances >=60-minutes){
        hours++;
        minutes=60-minutes+advances;
    }else{
        minutes +=advances;
    }
}

and it is called by

advanceTimeInMinutes( hour, minute, 50 );
Was it helpful?

Solution

In many programming languages, the name you use to refer to the object is distinct from the object itself. One object may have several names.

The most direct way to assign multiple names to one object in C++ is to declare a name with the & specifier. (This usage is different from the & operator; a specifier is not an operator.)

When you declare those parameters with &, they become aliases of the object passed as an argument to the function. Such names are known as references.

C++ has several (alright, many) kinds and categories of expressions. Two important concepts are modifiability and ownership. When you pass a reference to a function, you optionally give it permission to modify the object, and ownership of the object. Modifiability is indicated by the absence of the const specifier, and ownership is indicated by use of && instead of & (this is new in C++11).

A function is not allowed to get modifiable, non-owning access to an object with only transient existence, since it should be able to expect to write results into such an object for return to the caller. The value 50 is stored in such a transient object.

One solution is to use int const & advances, but a better solution is not to use a reference at all, because you're not really trying to use an aliasing name to refer to a shared object.


Many make a conceptual assumption that a reference is an automatically-dereferenced const pointer. This works pretty well, and compilers pretty much always do things that way. But it's not necessarily true. For example, given this class definition:

struct s {
    static int x;
    int &r = x;
    char c;
};

The compiler could determine that r is always referencing a the global x, and replace every use of r with x. With no need to store a reference in every object, sizeof(s) could legally be 1.

This is more advanced than current C++ code analysis, but it will inevitably come at some point. Future-proof code shouldn't expect implementation of references to be equivalent to pointers.

OTHER TIPS

& is a reference operator. It's used to change the value inside the function. The code above is equivalent to

void advanceTimeInMinutes(int *hours, int *minutes, int *advances)
{
    if(*advances >= 60 - *minutes){
        (*hours)++;
        *minutes = 60 - *minutes + *advances;
    }else{
        *minutes += *advances;
    }
}

advanceTimeInMinutes(&hour, &minute, &50);

As a number has no address, it'll cause an error

You can't pass a literal value as a reference. Since you never set the advance argument, then don't pass it by reference, so remove the & for that argument (and make it const as well (the fun thing is, if you make the argument const then you can use a reference)).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top