Pointer to Members

It is possible to take the address of a member of a class and assign it to a pointer. The address of a member can be obtain by applying the operator & to a "fully qualified" class member name. A class member pointer can be declared using the operator ::* with the class name.For example, given the class

class A
{
private:
int m;
public:
void show();
};
We can define a pointer to the member m as follows:
int A::* ip= &A :: m;
The ip pointer created thus acts like class member in that it must be invoked with a class object. The phrase A::* means "pointer to member of a class". The phrase &A::m means the "address of the m member of A class".

Remember, the following statement is not valid:

int *ip = &m;

const Member Function

If a member function does not alter any data in the class, then we may declare it as a const member function as fallows:

void mul(int ,int) const;
double get_balance() const;

The qualifier const is appended to the function prototype. The compiler will generate an error message if such functions try to alter the data values.

A friend function possesses certain special characteristics:

  • It is not in the scope of the class to which it has been declared as friend.
  • Since it is not in the scope of the class, it cannot be called using the object of that class.
  • It can be invoked like a normal function without the help of any object.
  • member function, it cannot access the member names directly and has to use an object name and dot membership operator with each member name.
  • It can be declared either in the public or the private part of a class without affecting its meaning.
  • Usually, it has the objects as arguments.

Friendly Functions

A non member function cannot have an access to the private data of a class. However, there could be a situation where we would like two classes to share a particular function. For example, consider a case where two classes, manager and scientist, have been defined. We would like to use a function income_tax() to operate on the object of both these classes. In such situations, C++ allows the common function to be made friendly with both the classes, thereby allowing the function to have access to the private data of these classes. Such a function need not be member of any of these classes.

To make an outside function "friendly" to a class, we have to simply declare this function as a friend of the class as shown below:

class ABC
{
.....
.....
public:
.....
.....
friend void xyz(void);
};

Array of Objects

We know that an array can be of any data type including struct. Similarly, we can also have array of variables that are of the type class. Such variables are called arrays of objects. Consider the following class definition:

class employee
{
char name[30];
float age;
public:
void getdate(void);
void putdata(void);
};

Static Member Functions

Like static member variable, we can also have static member function. A member function that is declared static has the following properties:
  • A static function can have access to only static members declared in the class.
  • A static member function can be called the class name as follows:

class-name :: function-name;

The static function showcount() displays the number of objects created till that moment. A count of number of objects created is maintained by the static variable count.
The function showcode() displays the code number of each object.

Static Data Members

A data member of a class can be qualified as static. The properties of a static member variable are similar to that of a C static variable. A static member variable has certain special characteristics. These are:
  • It is initialized to zero when the first object of its class is created. No other initialization is permitted.
  • Only one copy of that member is created for the entire class and is shared by all the objects of that class, no matter how many objects are created.
  • It is visible only within the class, but its lifetime is the entire program.

Static variables are normally used to maintain values common to the entire class. For example, a static data member can be used as a counter that record the occurrences of all the objects.Program illustrates the use of a static data member.

#include
using namespace std;

class item
{
static int count;
int number;
public:
void getdata(int a)
{
number = a;
count ++;
}
void getcount(void)
{
cout << "Count: ";
cout << count <<"\n";
}
};
int item :: count;

int main()
{
item a,b,c;
a.getcount();
b.getcount();
c.getcount();

a.getdata(100);
b.getdata(200);
c.getdata(300);

cout << "After reading data"<<"\n";
a.getcount();
b.getcount();
c.getcount();
return 0;
}

The output of the program would be:
Count: 0
Count: 0
Count: 0
After reading data
Count: 3
Count: 3
Count: 3

Array within a Class

The array can be used as member variables in a class. The following class definition is valid.

const int size=10;

class array
{
int a[size];
public:
void setval(void);
void display(void);
};

The array variable a[] declared as private member of the class array can be used in the member function, like any other array variable. We can perform any operations on it. For instance, in the above class definition, the member function setval() sets the value of element of the array a[], and display() function displays the values. Similarly, we may use other member functions to perform any other operation on the array values.

Private Member Functions

Although it is normal practice to place all the data items in a private section and all the function in public, some situations may require certain function to be hidden from the outside calls. Tasks such a deleting an account in a customer file, or providing increment to an employee are event of serious consequences and therefore the function handling such task should have restricted access. We can place these function in the private section.

A private member function can only be called by another function that is a member of its class. Even an object cannot invoke a private function using the dot operator. Consider a class as defined below:
class sample
{
int m;
void read(void);
public:
void update(void);
void write(void);
};

Nesting of Member Functions

A member function of a class can be called only by an object of that class using a dot operator. However, there is an exception to this. A member function can be called by using its name inside another member function of the same class. This is known as nesting of member functions.

Nesting of Member Function
#include
using namespace std;
class set
{
int m,n;
public:
void input(void);
void display(void);
void largest(void);
};
int set :: largest(void)
{
if(m >= n)
return(m);
else
return(n);
}
void set :: input(void)
{
cout << "Input value of m and n"<<"\n";
cin >> m>>n;
}
void set :: display(void)
{
cout << "largest value=" << largest() <<"\n";
}

int main()
{
set A;
A.input();
A.display();

return 0;
}

The output of program would be:
Input value of m and n
25 18
Largest value=25

Making an Outside Function Inline

One of the objectives of OOP is to separate the details of implementation from the class definition. It is therefore good practice to define the member functions outside the class.

We can define a member function outside the class definition and still make it inline by just using the qualifier inline in the header line of the function definition.
Example:
class item
{
......
......
public:
void getdata(int a,float b);
};
inline void item :: getdata(int a,float b)
{
number=a;
cost=b;
}

Outside the Class Definition

Member functions that are declared inside a class have to be defined separately outside the class. Their definition are very much like the normal functions. They should have a function header and a function body. Since C++ does not support the old version of function definition, the ANSI prototype from must be used for defining the function header.

An important difference between a member function and a normal function is that a member function incorporates a membership identity label in the header. This label tells the compiler which class the function belongs to. The general form of a member function definition is:
return_type class_name :: function_name (argument declaration)
{
function body
}

Defining Member Functions

Member functions can be defined in two places:

1. Outside the class definition.
2. Inside the class definition.

It is obvious that, irrespective of the place of definition, the function should perform the same task. Therefore, the code for the function body would be identical in both the cases. However, there is a subtle difference in the way the function header is defined.

Specifying a Class

A class is a way to bind the data and its associated functions together. It allows the data (and functions) to be hidden, if necessary, from external use. When defining a class, we are creating a new abstract data type that can be treated like any other build-in data type.
Generally, a class specification has two parts:
1. Class declaration
2. Class function definitions

The class declaration describes the type scope of its members. The class function definitions describe how the class functions are implemented.

The general form of a class declaration is:
class class_name
{
private:
variable declaration;
function declaration;
public:
variable declaration;
function declaration;
};

C Structure Revisited

We known that one of the unique feature of the C language is structures. They provide a method for packing together data of different types. A structure is a convenient tool for handling a group of logically related data items. It is a user define data type with a template that serves to define its data properties. Once the structure type has been defined, we can create variables of that type using declaration that are similar to the built in type declaration.For example, consider the following declaration:

struct student
{
char name[20];
int roll_number;
float total_marks;
};

The keyword struct declare student as a new data type that can hold three fields of different data types. These field are known as structure member or elements. The identifier student, which is referred to as structure name or structure tag, can be used to create variables of type student. Example:

struct student A; // C declaration

A is a variable of type student and has three member variables as defined by the template. Member variable can be accessed using the dot or period operator as fallows:

strcpy(A.name, "John");
A.roll_number = 999;
A.total_marks = 595.5;
final_total = A.total_marks + 5;
Structure can have arrays, pointer or structure as members.

Friend and Virtual Functions

C++ introduce two new types of functions, namely, friend function and virtual function. They are basically introduced to handle some specific tasks related to class objects. Therefore, discussions on these functions have been reversed until after the class object are discuss.

Function Overloading

As stated earlier, overloading refers to the use of the same thing for different purposes. C++ also permits overloading of functions. This means that we can use the same function name to create functions that perform a variety of different tasks. This is known as function polymorphism in OOP.

Using the concept of function overloading; we can design a family of functions with one function name but with different argument lists. The function would perform different operations depending on the argument list in the function call. The correct function to be invoke is determine by checking the number and type of the arguments but not on the function type. For example, an overload add() function handles different types of data as shown below:

// Declarations
int add(int a,int b);
int add(int a,int b,int c);
double add(double x,double y);
double add(int p,double q);
double add(double p,int q);

// Function calls
cout << add(5,10);
cout << add(15,10.0);
cout << add(12.5, 7.5);
cout << add(5,10,15);
cout << add(0.75,5);

const Arguments

In C++, an argument to a function can be declared as const as shown below:
int strlen(const char *p)
int length(const string &s);
The qualifier const tells the complier that the function should not modify the argument. The compiler will generate an error when this condition is violated. This type of declaration is significant only when we pass arguments by reference or pointers.

Default Arguments

C++ allows us to call a function without specifying all its arguments. In such cases, the function assigns a default value to the parameter which does not have a matching argument in the function call. Default value are specified when the function is declared. The compiler looks at the prototype to see how many argument a function uses and alert the program for possible default value. Here is an example of a prototype with default values:

float amount (float principle, int period, float rate=0.15);

The default value is specified in a manner syntactically similar to a variable initialization. The above prototype is declare a default value of 0.15 to the argument rate. A subsequent function call like

value = amount (5000,7); // one argument missing
passes the value of 5000 to principle and 7 to period and then lets the function use default value of 0.5 for rate. The call
value = amount (5000,5,0.12); //no missing argument

passes an explicit value of 0.12 to rate.

Inline Functions

One of the objective of using functions in a program is to save some memory space, memory becomes appreciable when a function is likely to be called many times. However, every time a function is called, it take a lot of extra time in executing a series of instruction for tasks such as jumping to the function. When a function is small, a substantial percentage of execution time may be spent in such overheads.
C++ has a different solution to this problem. To eliminate the cast of calls to small functions, C++ proposes a new feature called inline function. An inline function is a function that is expanded in line when it is invoke. That is, the compiler replace the function call with the corresponding function code. The inline functions are define as fallows:
inline function-header
{
function body
}
Example:
inline double cube(double a)
{
return(a*a*a);
}

The above inline function can be invoked by statements like
c = cube(3.0);
d = cube(2.5+1.5);

Return by Reference

A function can also return a reference. Consider the following function:
int & max (int &x, int &y)
{
if (x > y)
return x;
else
return y;
}

Since the return type of max() is int &, the function returns reference to x or y. Then a function call such as max (a,b) will yield a reference to either a or b depending on their values. This means that this function call can appear on the left hand side of an assignment statement. That is, the statement
max (a,b) = -1;
is legal and assigns -1 to a if it is larger, otherwise -1 to b.

Call by Reference

In traditional C, a function call passes arguments by value. The called function create a new set of variable and copies the value of argument into them. The function does not have access to the actual variable in the calling program and can only work on the copies of values. This machanism is fine if the function does not need to alter the values of the original variables in the calling program. But, there may arise situation where we would like to change the value of the variables in the calling program. For example, in bubble sort, we compare two adjacent element in the list and interchange their values if the first element is greater than the second. If a function is used for bubble sort, then it should be able to alter the value of the variable in the calling function, which is not possible if the call-by-value method is used.

Function Prototyping

Function prototyping is one of the majore improvements added to C++ function. The prototype describes the function interface to the compiler by giving details such as the number and type of arguments and the type of return values. With function prototyping, a template is always used when declaring and defining a function. When function is called, the compiler uses the template to ensure that proper arguments are passed, and the return value is treated correctly. Any violation in matching the arguments or the return types will be caught by the compiler at the time of compilation itself. These checks and controls did not exist in the conventional C function.

Function prototype is a declaration statement in the calling program and is of the following form:
type function-name (argument-list);
The argument-list contains the types and names of arguments that must be passed to the function.

Example:
float volume (int x, float y, float z);

The Main Function

C does not spefify any return type for the main() function which is the starting point for the execution of a program. The definition of main() would look like this:

main()
{
// main program statements
}
This is perfectly valid because the main in C does return any value.
In C++, the main return a value of type int to be operating system. C++, therefore explicitly defines main() as matching one of the following prototypes:
int main()
int main(int argc, char *argv[]);

The function that have a return value should use the return statement for termination. The main() function in C++ is, therefore, define as fallows:
int main()
{
.......
.......
return 0;
}