Tuesday, June 23, 2009

TRICKY WAYS OF FUNCTION OVERLOADING

Most of the guys knew about Function Overloading – declaring more than one functions of the same name, it will differ in number of parameters or type of parameters but not depends on return type. For example,


int add(int a, int b)
{
    return (a+b);
}

float add(float a, float b)
{
    return (a+b);
}


Let’s invoke these functions:



    add(5+6); // invokes int-version of add function


    add(5.7+6.8) // invokes float-version of add function



As you can see that which version of add-function is going to be invoked depends on the parameters a caller passed. So one can invokes different versions of methods using same name that can give different functionality – that is nothing but implementation of Polymorphism (static Polymorphism, as function calls are resolved during compile time).

Now we will look into other ways of function overloading. To explain it properly, consider following example:


class CTest
{
public:

    int add(int a, int b)
    {
        cout<<"CTest::add(pass-by-value version)";
        return (a+b);
    }
    int add(int *a, int *b)
    {
        cout<<"CTest::add(pass-by-pointer version
        return (*a + *b);
    }


    void display()
    {
        cout<<"CTest::display(non-const version)";
    }
    void display() const
    {
        cout<<"CTest::display(const version)";
    }

};


Here, class CTest defines two versions of add() function as:


int add(int a, int b) – accepts pass-by-value parameters
int add(int *a, int *b) – accepts pass-by-pointer parameters



Both add functions accept same number of parameters (2 parameters) of same type (int), so according to general rules of function overloading – this case doesn’t seem to be overloaded functions. But let’s try to invoke these functions,
CTest objTest;
Int aVar = 5, bVar = 6;

objTest.add(aVar, bVar); // invokes pass-by-value version of add
Output: CTest::add(pass-by-value version)
objTest.add(&aVar, &bVar); // invokes pass-by-pointer version
Output: CTest::add(pass-by-pointer version)

As you can observe that,

> First function call invokes pass-by-value version of add method as the parameters are passed by value
> Second function call invokes pass-by-pointer version of add method as the parameters are passed by addresses.

Hence this is the case of function overloading.

Class Ctest also defines two versions of display() function as:

void display();
void display() const;


Let’s try to invoke these functions,

CTest objTest;
objTest.display(); // obviously invokes non-const version of display
Output: CTest::display(non-const version)

Now, modify above code a little-bit and see the results,

const CTest objTest;
objTest.display(); // surprise!!! Invokes const version of display
Output: CTest::display(const version)

The const keyword makes objTest as a constant object, so when there is call to display method it’s going to be resolved as
Display(const CTest &objTest)
This indicates that user is passing a constant object which doesn’t allow others to change it’s member variables, and who is the right candidate to make sure this? – it’s our constant member function.

This case also represents function overloading.

Summary
Function overloading depends on:
> number of parameters
> type of parameters
> how parameters are passed – pass-by-value or pass-by-pointer
> constness of function

I hope this explanation gives you some idea about some tricky ways of function overloading. Any suggestions, feedbacks are always welcome.

No comments:

Post a Comment