8 Functions in C++ II

Jyoti Pareek

epgp books

In earlier section, we have seen declaration and definition of the function. Declaration of a function includes stating to a compiler that the declared function is defined in the program.

 

Function Prototyping and its Definition

 

Declaring a function is known as function prototyping. In C++, function prototyping is mandatory unlike C programs. Compiler error would be raised if a function is called without its prototype mentioned in the program before calling of the function. This is because In C, functions are identified only by their name. And in C++, a function’s signature includes its name, parameters, and (for member functions) const. It does NOT include the return type. A function signature is what the compiler and linker use to identify a function.

 

If a programmer writes a function to add two integers, It can be named as add and prototype of which can be written as int add(int , int) if returns integer. A function prototype is useful while checking whether the function when called is called with correct set of arguments. Definition of function includes instructions to be executed whenever function is called. Instructions written within a function may make use of arguments supplied through calling function.

 

Function Overloading

 

Assume a programmer intends to add two floating point numbers or one integer and one float, and a function is called using 4 and 67.5 as arguments, the value 67.5 would be truncated to integer. Function with name add can also be intended to concatenate two strings where string1 and string2 are arguments and its concatenation shall be returned. Compiler would raise error if string is passed in the add function with prototype int add(int, int) and neither it would return string.

 

Function overloading can be defined as a mechanism which allows programmer to define function with same name but different types of arguments or number of arguments.

 

Thus in the case explained above three different functions can be written whose prototypes and definitions would be different but their name would remain same.

 

In C++ it is possible to define more than one function with the same name in the same scope. Hence in C++ it is possible to define following three functions in same scope.

 

int Add(int x, int y);

 

int Add(int x, int y, int z);

 

float  Add(float x, float y);

 

This phenomena of defining more than one function with the same name is called function overloading.

 

When you call an overloaded function, the compiler determines the most appropriate definition to use by comparing the argument types you used to call the function with the parameter types specified in the definitions. The process of selecting the most appropriate overloaded function or operator is called overload resolution.

 

 

 

But Compiler will allow function overloading only when, it does not create any ambiguity and compiler can clearly do overload resolution. For example we cannot have following functions

 

int dowork(int x, int y);
double dowork(int x, int y);
Because
int input1,input2;
dowork(input1,input2); // call can not determine which function is to be called

 

Also following program too will create ambiguity for compiler and therefore will not successfully compile.

 

 

 

 

 

Default Arguments

 

 

Functions in C++ can have default arguments. That is we can provide default values for some arguments. For Example

 

Void Demo(int data, int value=10)

{

………….

 

………….

}

 

At the Time of calling we need not necessarily provide value for that argument. We can also call above function as follows

 

Demo(20);

 

Default arguments are useful in situation where a arguments has the same value in most function calls.

 

When the desired value is different from the default value,

 

the desired value can be specified explicitly in a function call as shown in the following program. This changes the default value of the argument to be overridden for the duration of function call. If in the function call all the arguments are not specified then the omitted arguments can take default value by providing them in the function declaration

Default arguments remove the need of passing arguments, but they reduce readability. Therefor they should be used with caution.

 

Making static variable default

 

We can also make static variable default; an interesting use of making static variable default can be seen as follows

 

Friend Functions

 

Data hiding is one of the important concepts of Object Oriented Programming. It says that a nonmember function cannot access an object’s private or protected data. C++ however provides programmer flexibility to access object’s private or protected data though a nonmember function, if that function is declared as friend of class. The complier understands that a given function is a friend function preceded by its keyword friend. The declaration of friend function should be made inside the body of class starting with keyword friend. The definition of function is similar to normal function. No keywords in used in function definition of friend function.

 

Following Program illustrates use of friend function. A class named Room with length and breadth as its private data members and a constructor is defined. A non-member function totalTiles is declared within a class preceded by word friend. Argument of friend function totalTiles is object of type Room. The definition of totalTiles is defined outside the class where it is expected to calculate number of tiles of specific area required in a room. As friend function is capable of accessing private data members of class Room, it can calculate area of room and can return total number of tiles required for flooring.

/*Program : C++ program to demonstrate the working of friend function.*/

 

#include <iostream>

#include<cmath>

 

using namespace std;

 

class Room

{

private:

 

int length;

int breadth;

public:

Room(int l, int b){ length = l; breadth = b; }

friend int totalTiles(Room);  //friend function

 

};

int totalTiles(Room a)            //function definition

{

int aTile;

 

cout<<endl<< “Enter area of Tile in square meters: “; cin>> aTile;

 

//accessing private data from non-member function

 

int areaRect= a. length * a. breadth;

int nTiles = ceil(areaRect / aTile);

 

return nTiles;

}

 

int main()

{

Room r(10,20);

 

cout<<endl<< ” Tiles Required: “<<totalTiles(r);

return 0;

}

Execution of Program

 

The above program gives us an idea about the concept of friend function. Logical usage of friend functions can solve complex problems.

 

Suppose, programmer needs to operate on objects of two different classes then, friend function can be very helpful. There are ways to write a program without friend functions but programs  would be longer, complex and hard to understand in that case. Following program illustrates utility of friend function in function overloading. Here we intends to find out number of tiles required for flooring a room defined through a class named Room, however tiles could be either square or rectangle. Two different classes exists for Square tiles and Rectangle tiles. A function named totalTiles is defined which accepts object of Square tiles and object of Room. totalTiles function would return number of tiles required for flooring. totalTiles function is overloaded with different set of arguments. Overloaded function totalTile accepts two arguments, first is object of class rectangleTile and other is object of room. Complier would accept overloading of totalTiles as object type is different in both the cases.

 

/* Program : C++ program to operate on Objects of two Different class using friend Function*/

 

#include <iostream>

 

#include<cmath>

 

using namespace std;

 

/* Forward declaration of class squareTile and rectangleTile */

 

class squareTile;

class rectangleTile;

 

class Room

{

private:

int length;

int breadth;

 

public:

Room(int l, int b){ length = l; breadth = b; }

int getroomArea() { return ( length * breadth); }

 

friend int totalTiles(squareTile sT, Room r); //friend function friend int totalTiles(rectangleTile rT, Room r); //friend function

};

class squareTile

{

private:

int length;

public:

squareTile(int l){length=l;}

friend int totalTiles(squareTile sT, Room r); //friend function

};

class rectangleTile

{

private:

int length, breadth;

public:

rectangleTile(int l, int b){length=l;breadth = b;}

 

friend int totalTiles(rectangleTile rT, Room r); //friend function

};

int totalTiles(rectangleTile rT, Room r) {

//function definition

int areaRoom = r.getroomArea(); int areaTile=rT.length * rT.breadth; int nTiles = ceil(areaRoom / areaTile); return (nTiles);

//accessing private data from non-member function

}

int totalTiles(squareTile sT, Room r) {

//function definition

int areaRoom = r.getroomArea();

int areaTile=sT.length * sT.length;

int nTiles = ceil(areaRoom / areaTile);

return nTiles;

//accessing private data from non-member function

}

int main()

{

Room r(50,20);

rectangleTile rT(2,3);

squareTile sT(2);

cout<<endl<<” Area of room is ” << r.getroomArea(); cout<<endl<< ” Rectangle Tiles Required is ” << totalTiles(rT, r);

cout<<endl<< ” Square Tiles Required is ” << totalTiles(sT, r); return 0;

}

 

Above program includes forward declaration of class squareTile and rectangleTile is to be made. It is because class Room is referencing object of class squareTile and rectangleTile while declaring following two friend functions.

 

friend int totalTiles(squareTile sT, Room r);

 

friend int totalTiles(rectangleTile rT, Room r);

 

Execution of program can be seen below

Execution of program : demonstrating utility of friend function.

 

Properties of Friend function

 

As friend functions come into the category of special functions in C++, it is advantageous to understand scope of functionalities of friend function. Following are the properties of Friend Function.

 

  • Friend function of the class can be member of some other class.
  • Friend function of one class can be friend of all the classes in one program, such a friend is referred as Global Friend.
  • Friend can access the private or protected members of the class in which they are declared Friends are non-member functions and hence do not have “this” pointer pointing to themselves.

 

Friend can be declared anywhere (in public, protected or private section) in the class.

 

Pointer to Function

 

We can define pointer to function as follows

 

Return Type (*functionName) ( dataType arg1, dataType arg2, dataType arg3, …………..);

 

 

For example we can define pointer to an integer function, which takes two parameter, int and float respectively as follows :

 

int    (*function_ptr) ( int  x, float y);

If we have two functions

nt  doWork(int data1, float data2);

int compute( int value1, float value2);

 

We can initialize function_ptr with any of the two functions

function_ptr = doWork;

function_ptr = compute;

 

Pointer to Member Function

 

We can also define pointer to member functions as follows Time t;

void   (Time :: *fptr)();

 

Here fptr is defined as pointer to any void member function without parameter of class Time. It can be made to point to any member function of class Time which does not take any argument and has void as a return type. We can make it to point to readTime() and displayTime() member functions of class Time as follows, as both are void functions with no arguments

 

fptr =  &Time :: readTime();

fptr =  &Time :: displayTime();

 

Member function can be called though pointer as follows t.(*fptr)();

 

Here if fptr is pointing to readTime(), this call will result into invokation of readTime() function on object t. If fptr is pointing to displayTime(), this call will result into invokation of displayTime() function on object t.

 

We can also initialize pointer to member function at the time of declaration as follows Time t;

void   (Time :: *fptr)() = &Time :: readTime()

 

Functions are powerful tools for creating modular design of program which is readable, effective , easy to modify, test, debug, and maintain……..

 

you can view video on Functions in C++ II

 

Additional References

 

1) Stanley Lippmann, “C++ Primer”, Pearson Education.

2) Bjarne Stroustrup, “The C++ Programming Language”, Pearson Education.

3) Scott Mayer, “Effective C++”, Addison Wesley.

4) Bhushan Trivedi , Programming with ANSI C++, 2/e , Oxford University Press.

5) Yashavant P. Kanetkar “Let Us C++” , Bpb Publications.

6) Abhiram G. Ranade, “An Introduction to Programming through C++” , McGraw Hill

7) Ellis and B. Stroustrup “Annotated C++ Reference Manual”, http://www.stroustrup.com/arm.html

8) Herbert Schildt, “Complete Reference C++”, McGraw Hill Publications.

9) Ashok Kamthane, “Object Oriented Programming with ANSI and Turbo C++”, Pearson Education

10) E Balaguruswami, “Object Oriented Programming With C++”, Tata McGraw Hill

11) “C++ FAQs”, Pearson Education.