Rotating an array around a pivot
June 12, 2012
C program output
June 12, 2012

Pass by Reference v/s Pass by value

In C language, everything is pass-by-value and C++ supports that. But C++ also provides provision to pass arguments by reference (by declaring new reference data type).
When should we use pass by reference. Will it have an impact on the performance if I pass by value or it is just another way to return more values from a function?

Solution:

Pass by reference in C++ has multiple usages. One of them (and not very significant) is to return multiple values from a function. Below function swap the actual arguments passed to it (and hence, in a way, is returning multiple values).

void swap(int &a, int&b)
{
    int temp = a;
    a = b;
    b = temp;
}

we all know that if the two arguments are passed-by-value, then the local copy of the variables in swap function will get changed. The actual arguments (of calling function) will not change in any way.

Somehow I find the term “call-by reference” misleading. It should be “Received-By Reference“. Because the caller function does not change.

Anyways, If we are passing primitive data types to a function (like int, float, double …) then there is no such performance implication (though there is a memory implication, because arguments passed by value have presence in the activation record of the called function).

But the story changes when we are dealing with user defined types. Because when you initialize one object with another, then Copy Constructor gets called. For example, If I have a below Test Class

class TestClass
{
  public:
    // Default Constructor
    TestClass()
    {
         cout << "Inside DEFAULT Constructor";
    }
    // Copy Constructor
    TestClass(TestClass& obj)
    {
         cout << "Inside Copy Constructor";
    }
}
TestClass obj1;        // Calls defualt constructor
TestClass obj2 = obj1  // Calls Copy constructor

And I have told earlier also that the semantics of parameter passing during function call is like initialization ( and not assignment ). So If I have a simple function which does nothing but accept an object of type TestClass and return the same object, like below.

TestClass myFunc(TestClass obj){
    return obj;
}

The above function just accept an object (by-value) and returns it (by-value). But look at the overhead of calling this function:

TestClass obj;
myFunc(obj);

When the argument is passed, copy constructor is called (and a new object is created). When it is returned then again a new object is created and copy constructor gets called again.

So a simple function call has 2 more function calls hidden in it.

But, this is not it. Since the 2 objects created will also be destroyed, so 2 calls to the destructor will also be there. It makes it 4 calls :).

I am not done yet..

Had, TestClass been the child class of a parent class, then the constructor of all the parent classes will also be called (and so will be the destructors).

There’s more 🙂

Had there been some properties(data members) in the class which are of non-primitive data types (for example, string), then those data members will also be constructed (and destroyed), so add the constructor and destructor call to those functions as well…

You saw, how dangerous this, innocent-looking function becomes when arguments are passed by value.

Leave a Reply

Your email address will not be published. Required fields are marked *