classISover
classISover

Reputation: 459

Using an & in C++

I was wondering how using an & to access a certain memory location changed the nature of a function call. For example, if I had written a function to set the radius of a circle

//True, if success, False if radius is off-screen
bool SetRadiusCircle(Circle &b, int r)

This was an example given in the assignment my professor gave me. I just wanted to know how the "&" he included in the sample function call differed from simply using Circle b.

Upvotes: 9

Views: 351

Answers (6)

Stefano Borini
Stefano Borini

Reputation: 143765

Yes. If you use &, you are passing the circle as a reference. If you don't use it, you are passing a copy of the circle object, copy that gets created by the compiler for you. This triggers the class copy constructor (either the one you defined, or the default one, which is a bitwise copy).

With a reference, you are not copying the object. You are instead getting the object you had in the caller. It's equivalent of having an alias to the original object, and any change you perform will apply to the object passed. In the case of a copy, any change to the object is lost at the end of the call, because the copy is destroyed.

When you use a reference, the internal use of that argument requires you to use the . to access that object's members (e.g. b.getRadius()). If you defined your function to accept a pointer instead (func (Circle *bPtr)) then you must use the -> (e.g. bPtr->getRadius()). Using a pointer is different from using a reference, but the final, practical effect is the same: you get to manipulate the original object, not a copy.

Note that this is valid in the function definition. An & used in another context gives you the pointer where something resides. They are not the same, although they use the same symbol.

Upvotes: 22

Alok Save
Alok Save

Reputation: 206508

The & here means a Reference.
It is just an alias to the variable being passed.

Any modification performed on b inside the function will result in modification of the Object being passed to the function.

Without the & an copy of the object will be passed to the function and any modification performed on it inside the function will not modify the Original Object.

Detailed explanation:

Consider the simple example below, it demonstrates the 3 ways in which you can pass arguments to a function:

Pass By value:

void passByValue(MyClass obj)

When an function argument is passed by value, the function receives an copy of the variable being passed, any modification done on this copy inside the function body does not affect the original variable being passed.

Pass an Reference:

void passAnRef(MyClass &ref)

The function receives an alias to the variable being passed.Any modification performed on this alias modify's the original variable as well. If the argument being passed is an custom class object then you can access the class members just like accesing through an object by using the . operator.

Pass an pointer:

void passAnPtr(MyClass *ptr)

The function receives an pointer to the original variable being passed. i.e: It receives an variable which points to address of original variable in memory. Any modification performed through this pointer modify's the original object since it just points to that memory.
If the argument being passed is an custom class object then you can access the class members just like accessing through an pointer to object by using the -> operator.

Online Demo:

#include<iostream>
using namespace std;

class MyClass
{
    public:
         int i;
         MyClass():i(0){}
};

void passByValue(MyClass obj)
{
    obj.i = obj.i + 10;

}
void passAnRef(MyClass &ref)
{
    ref.i = ref.i + 10;
}
void passAnPtr(MyClass *ptr)
{
    ptr->i = ptr->i + 10;
}

int main()
{
    MyClass obj;

    cout<<"Before passByValue obj is:"<<obj.i;
    passByValue(obj);
    cout<<"\nAfter passByValue obj is:"<<obj.i;

    cout<<"\nBefore passAnRef obj is:"<<obj.i;
    passAnRef(obj);
    cout<<"\nAfter passAnRef obj is:"<<obj.i;

    cout<<"\nBefore passAnPtr obj is:"<<obj.i;
    passAnPtr(&obj);
    cout<<"\nAfter passAnPtr obj is:"<<obj.i;

    return 0;
}

Output:

Before passByValue obj is:0
After passByValue obj is:0

Before passAnRef obj is:0
After passAnRef obj is:10

Before passAnPtr obj is:10
After passAnPtr obj is:20

Upvotes: 5

Kashyap
Kashyap

Reputation: 17411

Difference is Circle &c is passing by reference and Circle c is passing by value.

When passed by value a copy of the object is created, so e.g. if you change the object inside the function then change won't reflect outside the function. When passed by reference, you get a reference to the actual object and any change inside function would be visible to caller.

Needless to say "copy of object is created" means a call to copy c'tor.

E.g.

#include <iostream>

class My {
public: int x;
};

void byVal(int a, My m) {
    std::cout << "\tentry byVal(): " << i << "--" << m.x << std::endl;
    ++a; ++m.x;
    std::cout << "\texit byVal(): " << i << "--" << m.x << std::endl;
}

void byRef(int &a, My &m) {
    std::cout << "\tentry byRef(): " << i << "--" << m.x << std::endl;
    ++a; ++m.x;
    std::cout << "\texit byRef(): " << i << "--" << m.x << std::endl;
}

int main() {
    My m; m.x = 10; int i = 10;
    std::cout << "before: " << i << "--" << m.x << std::endl;
    byVal(a,m);
    std::cout << "after byVal(): " << i << "--" << m.x << std::endl;
    byRef(a,m);
    std::cout << "after byRef(): " << i << "--" << m.x << std::endl;
}

would print

    before: 10 -- 10
        entry byVal(): 10 -- 10
        exit byVal(): 11 -- 11
    after byVal():  10 -- 10
        entry byRef(): 10 -- 10
        exit byRef(): 11 -- 11
    after byRef():  11 -- 11

Upvotes: 1

Seva Alekseyev
Seva Alekseyev

Reputation: 61341

The & makes the function accept a reference to a Circle object as opposed to a Circle object. With this, any changes done to the Circle inside the function are visible to the caller.

Without the &, the function call would make a copy of its Circle parameter and pass the copy into the function. So the function would get its private Circle that is initialized from the caller's one. Whatever it does to that Circle stays inside the function, the caller won't notice.

Note that passing objects by reference is the norm. No one typically wants the overhead of object copying upon every call.

Upvotes: 0

sam-w
sam-w

Reputation: 7687

The & indicates that you're passing a reference to the object, rather than the object itself. If you do any work on b within the function, you are working on the same instance of the object that you passed in, rather than a copy of it - i.e. a new instance.

Upvotes: 0

Alessandro Pezzato
Alessandro Pezzato

Reputation: 8802

with & if inside your function implementation you make some change to b, you are changing the object "outside" the function. Without & you are making changes to a temporary copy of b

Upvotes: 0

Related Questions