6. Classes and Objects – Object-Oriented Programming with ANSI and Turbo C++

6

CHAPTER

Classes and Objects

C
H
A
P
T
E
R

O
U
T
L
I
N
E
—• 6.1 Introduction
—• 6.2 Structures in C
—• 6.3 Structures in C++
—• 6.4 Classes in C++
—• 6.5 Declaring Objects
—• 6.6 The public Keyword
—• 6.7 The private Keyword
—• 6.8 The protected Keyword
—• 6.9 Defining Member Functions
—• 6.10 Characteristics of Member Functions
—• 6.11 Outside Member Function Inline
—• 6.12 Rules for Inline Functions
—• 6.13 Data Hiding or Encapsulation
—• 6.14 Classes, Objects and Memory
—• 6.15 Static Member Variables and Functions
—• 6.16 Static Object
—• 6.17 Array of Objects
—• 6.18 Objects as Function Arguments
—• 6.19 friend Functions
—• 6.20 The const Member Function
—• 6.21 Recursive Member Function
—• 6.22 Local Classes
—• 6.23 Empty, Static and Const Classes
—• 6.24 Member Functions and Non- Member Functions
—• 6.25 The main( ) as a Member Function
—• 6.26 Overloading Member Functions
—• 6.27 Overloading main( ) Function
—• 6.28 The main( ), Member Function and Indirect Recursion
—• 6.29 Bit Fields and Classes

6.1 INTRODUCTION

In C, structures are used to combine one or more data types. Functions are not permitted as members in structures. Later objects are declared which hold individual copies of member variables of structure. Objects can access the data members of the structures directly. Any outside function is also able to access the data members of the structure through the object. Thus, there is no security to member variables declared inside the structure in C as shown in Figure 6.1.

Fig.6.1 Structure in C

In C++, structure also combines functions with data members. C++ introduces a new keyword class. A class in C++ is similar to structure. Using class or structure, a programmer can merge one or more dissimilar data types and a new custom data type can be created. A class is nothing but grouping of variables of different data types with functions. Each variable of a class is called as member variable. Functions are called as member functions or methods.

In C++, it is possible to restrict access to data members directly by objects which is not possible in C. It is always a programmer's choice to allow or disallow direct access to data members. The mechanism of restricting access to data outside the class is called as data hiding or encapsulation. In such a case, only the member functions can access the data. If class is used in place of struct, it restricts the access to data members as shown in Figure 6.2.

Fig.6.2 Class in C++

6.2 STRUCTURES IN C

Though, it is possible to combine more than one variable using structure in C, the structure has following limitations when used in C:

(a) Only variables of different data types can be declared in the structure as member, functions are not allowed as members.

(b) Direct access to data members is possible. It is because by default all the member variables are public. Hence, security to data or data hiding is not provided.

(c) The struct data type is not treated as built in type i.e., use of struct keyword is necessary to declare objects.

(d) The member variables cannot be initialized inside the structure.

The syntax of structure declaration is as follows:

Syntax:

struct   <struct name>
{
   Variable1;

   Variable2;
};

Example:

struct  item
{
   int codeno;
   float prize;
   int  qty;
};

In the above example, item is a structure name. The variables codeno, prize and qty are member variables. Thus, a custom data type is created by a combination of one or more variables.

The object of structure item can be declared as follows:

  struct item a,*b

The object declaration is same as declaration of variables built in data types. The objecta and pointer *b can access the member variables of struct item. Use of keyword struct is necessary.

The operators (• ) dot and (->) arrow are used to access the member variables of struct. The dot operator is used when simple object is declared and arrow operator is used when object is pointer to structure. The access of members can be accomplished as per the syntax given below:

[Object name][Operator][Member variable name]

When an object is a simple variable, access to members is done as below:

a.codeno
a.prize
a.qty

When an object is a pointer to structure then members are accessed as below:

a->codeno
a->prize
a->qty

The following program illustrates the above discussion.

6.1 Write a program to declare structure, access and initialize its members using object of structure type.

# include <stdio.h>
# include <conio.h>


struct item     // struct declaration
{
   int   codeno;    // codeno=200 not possible as per 6.2 section
   float prize;
   int   qty;

};

void main( )
{
   struct item a,*b;    // object declaration
   clrscr( );
   a.codeno=123; // direct access & initialization of member variables
   a.prize=150.75;
   a.qty= 150;


   printf ("\n With simple variable");
   printf ("\n Codeno : %d ",a.codeno);
   printf ("\n Prize  : %d",a.prize);
   printf ("\n Qty    : %d",a.qty);


   b->codeno=124;  // direct access & initialization of member variables
   b->prize=200.75;
   b->qty= 75;


   printf ("\n\n With pointer  variable");
   printf ("\n Codeno : %d ",b->codeno);
   printf ("\n Prize  : %d",b->prize);
   printf ("\n Qty    : %d",b->qty);
}

OUTPUT
With simple variable
Codeno : 123
Prize : 150.75
Qty : 150

With pointer to structure
Codeno : 124
Prize : 200.75
Qty : 75

Explanation: The above program is compiled with C compiler. The following discussion is in accordance with C compiler. In the above program, the structure item is declared with three member variables. The initialization of member variables inside the struct is not permitted. The declaration of member variables is enclosed within the curly braces. The struct declaration is terminated by semi-colon.

In function main( ), the objects a and b are declared. Consider the following statement:

  struct item a,*b; // object declaration

The struct must be preceded by structure name. The member variables can be accessed and initialization is done directly by object. The dot and arrow operators are used to access the member variables.

6.3 STRUCTURES IN C++

No doubt, C++ has made various improvements in structure. To know the improvements made in C++, the last program is compiled and executed with C++ compiler. The explanation followed by this program discusses the various improvements.

6.2 Write a program to declare struct. Initialize and display contents of member variables.

# include <iostream.h>
# include <constream.h>



struct item     // struct declaration
{
   int   codeno;    // codeno=200 not possible
   float prize;
   int   qty;
};


void main( )
{
   item a,*b;    // object declaration
   clrscr( );
   a.codeno=123; // direct access & initialization of member variables
   a.prize=150.75;
   a.qty= 150;


   cout <<"\n With simple variable";
   cout <<"\n Codeno : "<<a.codeno;
   cout <<"\n Prize  : "<<a.prize;
   cout <<"\n Qty    : "<<a.qty;


   b->codeno=124; // direct access & initialization of member variables
   b->prize=200.75;
   b->qty= 75;

   cout <<"\n\n With pointer to structure";
   cout <<"\n Codeno : "<<b->codeno;
   cout <<"\n Prize  : "<<b->prize;
   cout <<"\n Qty    : "<<b->qty;
}

Explanation: The above program is same as the last one. The output is also same, hence not shown. Consider the following statement:

  item a,*b; // object declaration in c++

While declaring an object the keyword struct is omitted in C++ which is compulsory in C. The structure item is a user-defined data type. C++ behaves structure data type as built in type and allows variable declaration.

C++ introduces new keyword class, which is similar to structure. The other improvements are discussed with use of class in the following section.

6.4 CLASSES IN C++

Classes and structure are the same with only a small difference that is explained later. The following discussion of class is applicable to struct too.

The whole declaration of class is given in Table 6.1. The class is used to pack data and function together. The class has a mechanism to prevent direct access to its members, which is the central idea of object-oriented programming. The class declaration is also known as formation of new abstract data type. The abstract data type can be used as basic data type such as int, float etc. The class consists of member data variables that hold data and member functions that operate on the member data variables of the same class.

Table 6.1 Syntax and an example of class

 

Syntax of class declaration Example of class
class  <name of class>
{
    private:


    declaration of variables;
    prototype declaration of function;


    public:


    declaration of variables;
    prototype declaration of function;
};
class item     // class declaration
{
     private:
       int   codeno;
       float prize;
       int   qty;
       void values( );
     public:
     void show( );
};

The class and struct are keywords. The class declaration is same as struct declaration. The declaration of a class is enclosed with curly braces and terminated by a semi-colon. The member variables and functions are divided in two sections i.e., private and public. The private and public keywords are terminated by colon (:). The object cannot directly access the member variables and functions declared in private section but it can access the data member variables and functions declared in public section. The private members of a class can only be accessed by public member function of the same class. Different sections of a class are illustrated with examples in following sections.

It is also possible to access private member variables directly like public member variables provided that the class should have at least one public member variable. Both the private and public member variables are stored in consecutive memory locations in the memory. A pointer to member variable provides address of member variable. By applying increment (++) and decrement (--) operations on pointer, we can access all private and public member variables of the class. The object of a class contains address of the first member variable. It can also be used to access the private or public data.

6.5 DECLARING OBJECTS

A class declaration only builds the structure of object. The member variables and functions are combined in the class. The declaration of objects is same as declaration of variables of basic data types. Defining objects of class data type is known as class instantiation. When objects are created only during that moment, memory is allocated to them.

Consider the following examples:

(a) int x,y,z; // Declaration of integer variables

(b) char a,b,c; // Declaration of character variables

(c) item a,b, *c; // Declaration of object or class type variables

In example (a) three variables x, y and z of integer types are declared. In example (b) three variables a, b and c of char type are declared. In the same fashion the third example declares the three objects a, b and c of class item. The object *c is pointer to class item.

An object is an abstract unit having following properties:

(a) It is individual.

(b) It points to a thing, either physical or logical that is identifiable by the user.

(c) It holds data as well as operation method that handles data.

(d) It's scope is limited to the block in which it is defined.

(1) Accessing Class Members

The object can access the public member variables and functions of a class by using operator dot (.) and arrow (->). The syntax is as follows:

[Object name][Operator][Member name]

To have access to members of class item, the statement would be,

a.show( );

where a is an object and show( ) is a member function. The dot operator is used because a is a simple object.

In statement,

c->show( );

*c is pointer to class item; therefore, the arrow operator is used to access the member.

Consider the given example:

class item     // class declaration
{
   int   codeno;
   float prize;
   int   qty;
};

We replaced the struct keyword with class. If last few programs are executed with class, they won't work. For example,

void main ( )
{
   item a,*b;    // object declaration
   clrscr( );
   a.codeno=123;     // Direct access is not allowed
   a.prize=150.75;
   a.qty= 150;
}

The above program will generate error messages, one of them being “item::codeno' is not accessible”. This is because the object cannot directly access the member variables of class that is possible with structure. Hence, we can say that the difference between class and struct is that the member variables of struct can be accessed directly by the object, whereas the member variables of class cannot be accessed directly by the object.

6.6 THE public KEYWORD

In Section 6.3, we have noticed that the object directly accesses the member variables of structure whereas the same is not possible with class members. The keyword public can be used to allow object to access the member variables of class directly like structure. The public keyword is written inside the class. It is terminated by colon (:). The member variables and functions declared followed by the keyword public can be accessed directly by the object. The declaration can be done as below:

class item     // class declaration
{
   public:    // public section begins
   int   codeno;
   float prize;
   int   qty;
};

The following program illustrates the use of public keyword with class.

6.3 Write a program to declare all members of a class as public. Access the elements using object.

# include <iostream.h>
# include <constream.h>
class item
{
   public:               // public section begins
   int   codeno;
   float prize;
   int   qty;


};                     // end of class


int main( )
{
   clrscr( );
   item one;        // object declaration
   one.codeno=123;  // member initialization
   one.prize=123.45;
   one.qty=150;


   cout <<"\n Codeno   = "<<one.codeno;
   cout <<"\n Prize     ="<<one.prize;
   cout <<"\n Quantity ="<<one.qty;
   return 0;
}

OUTPUT
Codeno =123
Prize =123.449997
Quantity =150

Explanation: In the above program, the members of class item are declared followed by keyword public. The object one of class item, accesses the member variables directly. The member variables are initialized and values are displayed on the screen.

6.7 THE private KEYWORD

The private keyword is used to prevent direct access to member variables or function by the object. The class by default produces this effect. The structure variables are by default public. To prevent member variables and functions of struct from direct access the private keyword is used. The syntax of private keyword is same as public. The private keyword is terimnated by colon. Consider the given example.

struct item
{
   private:            //  private section begins
   int   codeno;
   float prize;
   int   qty;
};                     // end of class


int main ( )
{
   clrscr( );
   item one;           // object declaration
   one.codeno=123;     // member initialization
   one.price=123.45;
   one.qty=150;
}

As soon as the above program is compiled, the compiler will display following error messages:

‘item::codeno’ is not accessible
‘item::prize’ is not accessible
‘item::qty’ is not accessible
‘item::codeno’ is not accessible
‘item::prize’ is not accessible

From the above discussion, we noticed that by default (without applying public or private keyword) the class members are private (not accessible) whereas the struct members are public (accessible).

The private members are not accessible by the object directly. To access the private members of a class, member functions of the same class are used. The member functions must be declared in the class in public section. An object can access the private members through the public member function.

6.8 THE protected KEYWORD

The access mechanism of protected keyword is same as private keyword. The protected keyword is frequently used in inheritance of classes. Hence, its detailed description is given in the Chapter Inheritance. Table 6.2 illustrates the access difference between private, protected and public keywords.

Table 6.2 Access limits of class members

 

Access specifiers   Access permission  
Class members Class object
public allowed allowed
private allowed disallowed
protected allowed disallowed

6.9 DEFINING MEMBER FUNCTIONS

The member function must be declared inside the class. They can be defined in a) private or public section b) inside or outside the class. The member functions defined inside the class are treated as inline function. If the member function is small then it should be defined inside the class, otherwise it should be defined outside the class.

If function is defined outside the class, its prototype declaration must be done inside the class. While defining the function, scope access operator and class name should precede the function name. The following program illustrates everything about member functions and how to access private member of the class.

(1) Member Function inside the Class

Member function inside the class can be declared in public or private section. The following program illustrates the use of member function inside the class in public section.

6.4 Write a program to access private members of a class using member function.

# include <iostream.h>
# include <constream.h>


struct item
{
   private:          // private section  starts


   int   codeno;
   float price;
   int   qty;


   public:           // public section starts


   void show ( )      // member function
   {
      codeno=125;    // access to private members
      price=195;
      qty=200;


      cout <<"\n Codeno  ="<<codeno;
      cout <<"\n Price   ="<<price;
      cout <<"\n Quantity="<<qty;
   }


};

int main( )
{
   clrscr( );
   item one;         // object declaration
   one.show( );       // call to member function


return 0;
}

OUTPUT
Codeno =125
Price =195
Quantity=200

Explanation: In the above program, the member function show( ) is defined inside the class in public section. In function main( ), object one is declared. We know that an object has permission to access the public members of the class. The object one invokes the public member function show( ). The public member function can access the private members of the same class. The function show( ) initializes the private member variables and displays the contents on the console. For the sake of understanding only one function is defined.

In the above program, the member function is defined inside the class in public section. Now the following program explains how to define private member function inside the class.

(2) Private Member Function

In the last section, we have learnt how to access private data of class using public member function. It is also possible to declare function in private section like data variables. To execute private member function, it must be invoked by public member function of the same class. A member function of a class can invoke any other member function of its own class. This method of invoking function is known as nesting of member function. When one member function invokes other member function, the frequent method of calling function is not used. The member function can be invoked by its name terminated by semi-colon only like normal function. The following program illustrates this point.

6.5 Write a program to declare private member function and access it using public member function.

# include <iostream.h>
# include <constream.h>


struct item
{
   private:             // private section  starts
   int   codeno;

   float price;
   int   qty;


void   values( )         // private member function
{
      codeno=125;
      price=195;
      qty=200;


}
   public:              // public section starts


   void show( )        // public member function
   {
      values( );         // call to private member functions


      cout <<"\n Codeno  ="<<codeno;
      cout <<"\n Price   ="<<price;
      cout <<"\n Quantity="<<qty;
   }


};


int main( )
{
   clrscr( );
   item one;            // object declaration


   //   one.values( );   // not accessible


   one.show( );          // call to public member function
   return 0;
}

OUTPUT
Codeno =125
Price =195
Quantity=200

Explanation: In the above program, the private section of a class item contains one-member function values( ). The function show( ) is defined in public section. In function main( ), one is an object of class item. The object one cannot access the private member function. In order to execute the private member function, the private function must be invoked using public member function. In this example, the public member function show( ) invokes the private member function values( ). In the invocation of function values( ), object name and operator are not used.

(3) Member Function Outside the Class

In the previous examples, we observed that the member functions are defined inside the class. The function prototype is also not declared. The functions defined inside the class are considered as inline function. If a function is small, it should be defined inside the class and if large it must be defined outside the class. To define a function outside the class the following care must be taken:

(1) The prototype of function must be declared inside the class.

(2) The function name must be preceded by class name and its return type separated by scope access operator.

The following example illustrates the function defined outside the class.

6.6 Write a program to define member function of class outside the class.

# include <iostream.h>
# include <constream.h>


class item
{
   private:             // private section  starts


   int   codeno;        // member data variables
   float price;
   int   qty;


   public:              // public section starts


   void show (void);    // prototype declaration


};                      // end of class



void item:: show( )  // definition outside the class
   {
      codeno=101;
      price=2342;
      qty=122;


      cout <<"\n Codeno  ="<<codeno;

      cout <<"\n Price   ="<<price;
      cout <<"\n Quantity="<<qty;
   }


int main( )
{
   clrscr( );
      item one;         // object declaration
      one.show( );       // call to public member function
   return 0;
}

OUTPUT
Codeno =101
Price =2342
Quantity=122

Explanation: In the above program, the prototype of function show( ) is declared inside the class and followed by it class definition is terminated. The body of function show( ) is defined inside the class. Class name that it belongs to and its return type, precede the function name. The function declarator of function show( ) is as follows:

  void item:: show( )

Here, void is return type i.e., function is not returning a value. The item is a class name. The scope access operator separates the class name and function name and the body of function is defined after it.

6.10 CHARACTERISTICS OF MEMBER FUNCTIONS

(1) The difference between member and normal function is that the former function can be invoked freely where as the latter function only by using an object of the same class.

(2) The same function can be used in any number of classes. This is possible because the scope of the function is limited to their classes and cannot overlap one another.

(3) The private data or private function can be accessed by public member function. Other functions have no access permission.

(4) The member function can invoke one another without using any object or dot operator.

6.11 OUTSIDE MEMBER FUNCTION INLINE

In the last chapter we saw how inline mechanism is useful for small functions. It is a good practice to declare function prototype inside the class and definition outside the class. The inline mechanism reduces overhead relating to accessing the member function. It provides better efficiency and allows quick execution of functions. An inline member function is similar to macros. Call to inline function in the program, puts the function code in the caller program. This is known as inline expansion. Inline functions are also called as open subroutines because their code is replaced at the place of function call in the caller function. The normal functions are known as closed subroutines because when such functions are called, the control passes to the function.

By default, all member functions defined inside the class are inline functions. The member function defined outside the class can be made inline by prefixing the keyword inline to function declarator as shown in Figure 6.3.

Fig.6.3 Inline function outside the class

The inline is a keyword and acts as function qualifier. The return type is functions return type i.e., the function returns values of this type. The class name is the name of class that the function belongs to. Scope access operator separates class name and function name. Signature means argument list passed function. The following program illustrates inline function outside the class.

6.7 Write a program to declare outside function inline.

# include  <iostream.h>
# include  <constream.h>


class item
{
   private:                  // private section  starts


   int   codeno;             // member data variables
   float price;
   int   qty;


   public:                   // public section starts


   void show (void);         //  prototype declaration


};                           // end of class



inline void item:: show ( )   //  outside inline function
   {
     codeno=213;
     price=2022;
     qty=150;
     cout <<"\n Codeno  ="<<codeno;

     cout <<"\n Price   ="<<price;
     cout <<"\n Quantity="<<qty;
 }


int main( )
{
   clrscr( );
   item one;      // object declaration
   one.show( );   // call to public member function (inline)
   return 0;
}

OUTPUT
Codeno =213
Price =2022
Quantity=150

Explanation: The above program is the same as the last one. The only difference is that the function show( ) is defined as inline outside the class. The function declarator is inline void item:: show( ).

6.12 RULES FOR INLINE FUNCTIONS

(1) Use inline functions rarely. Apply only under appropriate circumstances.

(2) Inline function can be used when the member function contains few statements. For example,

inline int item :: square (int x)
{
   return (x*x);
}

(3) If function takes more time to execute, then it must be declared as inline. The following inline function cannot be expanded as inline:

inline void item:: show( )
{
   cout <<"\n Codeno  ="<<codeno;
   cout <<"\n Price   ="<<price;
   cout <<"\n Quantity="<<qty;
}

The member function that performs input and output operation requires more time. Inline functions have one drawback, the entire code of the function is placed at the point of call in caller function and it must be noted at compile time. Therefore, inline functions cannot be placed in standard library or run-time library.

6.13 DATA HIDING OR ENCAPSULATION

Data hiding is also known as encapsulation. It is a process of forming objects. An encapsulated object is often called as an abstract data type. We need to encapsulate data because the programmer often makes various mistakes and the data gets changed accidentally. Thus, to protect data we need to construct a secure and impassable wall to protect the data. Data hiding is nothing but making data variable of the class or struct private. Thus, private data cannot be accessed directly by the object. The objects using public member functions of the same class can access the private data of the class. The keywords private and protected are used for hiding the data. Table 6.3 shows the brief description of access specifiers. The following program explains data hiding:

6.8 Write a program to calculate simple interest. Hide the data elements of the class using private keyword.

# include <iostream.h>
# include <conio.h>


class interest
{
   private :
   float p_amount;     // principle amount
   float rate;         // rate of interest
   float period;       // number of  years
   float interest;
   float t_amount;     // total amount


public :
   void in( )
   {
      cout <<" Principle Amount : "; cin>>p_amount;
      cout <<" Rate of Interest : "; cin>>rate;
      cout <<" Number of years  : "; cin>>period;
      interest=(p_amount*period*rate)/100;
      t_amount=interest+p_amount;
}


void show( )
{
   cout <<"\n Principle Amount : "<<p_amount;
   cout <<"\n Rate of Interest : "<<rate;
   cout <<"\n Number of years  : "<<period;
   cout <<"\n Interest         : "<<interest;

   cout <<"\n Total Amount     : "<<t_amount;
}


};


int main( )
{
   clrscr( );
   interest r;
   r.in( );
   r.show( );
   return 0;
}

OUTPUT
Principle Amount : 5000
Rate of Interest : 2
Number of years : 3

Principle Amount : 5000
Rate of Interest : 2
Number of years : 3
Interest : 300
Total Amount : 530

Explanation: In the above program, the class interest is declared with the data members p_amount, float rate, period, interest and t_amount of float type. These entire data elements are declared in private section hence it is hidden (encapsulated) and cannot be directly accessed by the object. Here, member function in( ), is used to read data through the keyboard. The function show( ) is used to display the contents of the variables.

Table 6.3 Access specifiers and their scope

 

Access specifiers Members of the class Class objects
public access possible access possible
private access possible no access
protected access possible no access

As described in Table 6.3, the class object can access public member of the class directly without use of member function. The private and protected mechanism do not allow objects to access data directly. The object can access private or protected members only through public member functions of the same class. The following program explains the working of the above keywords.

6.9 Write a program to declare class with private, public and protected sections. Declare object and access data elements of these different sections.

# include <iostream.h>
# include <conio.h>


class access
{
   private :
   int p;


void getp ( )
{
   cout <<" In pget( ) enter value of p :";
   cin>>p;
}
public:
int h;


void geth( )
{
   cout <<" In geth( ) : "<<endl;
   getp( );
   getm( );


cout <<" p = "<<p <<" h = "<<h <<" m = "<<m;
}


protected :
int m;
void getm ( )
{
   cout <<" In mget( ) enter value of m : ";
   cin>>m;
}


};


void main( )
{

   clrscr( );
   access a;// object declaration
             // a.p=2; // access to private member is not possible
             // a.pget ( ) //   —————" ——————————
             // a.m=5;    // access to protected member is not possible
             // a.mget( ); // ————————" ——————————
   a.h=4;    // direct access to public member is possible
   a.geth( );


}

OUTPUT
In geth ( ) :
In pget ( ) enter value of p :7
In mget ( ) enter value of m : 4
p = 7 h = 4 m = 4

Explanation: In the above program, the class access is declared with private, protected and public sections. Each section holds one integer variable and one member function. The object cannot directly access the data variable and member function of the private and protected sections. The object can access only the public section of the class and through public section it can access the private or protected sections. Here, the object a accesses the public variable h and initializes it with 4 whereas the private and protected variables are accessed using member functions. The function getp( ) and getm( ) are invoked by the public member function geth( ). The geth( ) also displays the contents of the variables on the screen.

6.14 CLASSES, OBJECTS AND MEMORY

Objects are the identifiers declared for class data type. Object is a composition of one or more variables declared inside the class. Each object has its own copy of public and private data members. An object can have access to its own copy of data members and have no access to data members of other objects.

Only declaration of a class does not allocate memory to the class data members. When an object is declared memory is reserved for data members only and not for member functions.

Consider the following program.

6.10 Write a program to declare objects and display their contents.

# include <iostream.h>
# include <constream.h>


class month
{

 public:
 char *name;
 int   days;
};                    // end of class




int main ( )
{
 clrscr( );
 month M1,M3;          // object declaration
 M1.name="January";
 M1.days=31;
 M3.name="March";
 M3.days=31;


 cout <<"\n Object  M1 ";
 cout   <<"\n   Month   name   :   "<<M1.name   <<"   Address
:"<<(unsigned)&M1.name;
 cout <<"\n Days :" <<M1.days <<"\t\t Address : "<<(unsigned)&M1.days;


 cout <<"\n\n Object  M3 ";
 cout <<"\n Month name : "<<M3.name <<"\t Address :
      "<<(unsigned)&M3.name;
 cout <<"\n Days :" <<M3.days <<"\t\t Address : "<<(unsigned)&M3.days;


 return 0;
}

OUTPUT
Object M1
Month name : January Address :65522
Days : 31 Address : 65524

Object M3
Month name : March Address : 65518
Days : 31 Address : 65520

Explanation: M1 and M3 are objects of class month. Separate memory is allocated to each object. The contents and address of the member variables are displayed in the output. Figure 6.4 shows it more clearly.

From the last program it is clear that memory is allocated to data members. What about functions? Member functions are created and memory is allocated to them only once when a class is declared. All objects of a class access the same memory location where member functions are stored. Hence, separate copies of member functions are not present in every object like member variables. The following program and Figure 6.5 illustrates this.

Fig.6.4 Memory occupied by objects

6.11 Write a program to display the size of the objects.

# include <iostream.h>
# include <constream.h>


class data
{
   long i;    // By default private
   float f;
   char c;
};


int main( )
{
   clrscr( );
   data d1,d2;
   cout <<endl<<" Size of object d1 = "<<sizeof(d1);
   cout <<endl<<" Size of object d2 = "<<sizeof(d2);
   cout <<endl<<" Size of class       ="<<sizeof(data);
   return 0;
}

OUTPUT
Size of object d1 = 9
Size of object d2 = 9
Size of class = 9

Explanation: In the above program, the class data has three member variables of long, float and char type. d1 and d2 are objects of the class data. The sizeof( ) operator displays the size of objects. The size of any object is equal to sum of sizes of all the data members of the class. In the class data, the data type long occupies 4 bytes, float occupies 4 bytes and char occupies 1 byte. Their sum is 9 that is the size of an individual object.

Fig.6.5 Data members and member functions in memory

The member functions are not considered in the size of the object. All the objects of a class use the same member functions. Only one copy of member function is created and stored in the memory whereas each object has its own set of data members.

6.15 STATIC MEMBER VARIABLES AND FUNCTIONS

(1) Static Member Variables

We have noticed earlier that each object has its separate set of data member variables in memory. The member functions are created only once and all objects share the functions. No separate copy of function of each object is created in the memory like data member variables.

It is possible to create common member variables like function using the static keyword. Once a data member variable is declared as static, only one copy of that member is created for the whole class. The static is a keyword used to preserve value of a variable. When a variable is declared as static it is initialized to zero. A static function or data element is only recognized inside the scope of the present class.

In the earlier version of Turbo C++, it was not necessary to define static data members explicitly. It was linkers' responsibility to find undefined static data. The linker would implicitly define the static data and allocate them required memory without showing error message. In the new versions of Turbo C++, it is necessary to explicitly define static members.

Syntax:

Static <variable definition> ;
Static <function definition>;

If a local variable is declared with static keyword, it preserves the last value of the variable. A static data item is helpful when all the objects of the class share a common data. The static data variable is accessible within the class, but its value remains in the memory throughout the whole program. Figure 6.6 shows static members in memory.

Examples:

   Static int c;
   Static void display ( ) {}
(a) int sumnum :: c=0;

The class and scope of the static member variable is defined outside the class declaration as shown in statement (a). The reasons are:

(1) The static data members are associated with the class and not with any object.

(2) The static data members are stored individually rather than an element of an object.

(3) The static data member variable must be initialized otherwise the linker will generate an error.

(4) The memory for static data is allocated only once.

(5) Only one copy of static member variable is created for the whole class for any number of objects. All the objects have common static data member.

Fig.6.6 Static members in memory

6.12 Write a program to declare static data member. Display the value of static data member.

# include <iostream.h>
# include <constream.h>


class number
{
   static int c;


   public:


void count ( )
{
   ++c;
   cout <<"\n c="<<c;
}


};

int number :: c=0;  // initialization of static member variable


int main( )
{
   number a,b,c;
   clrscr( );
   a.count( );
   b.count( );
   c.count( );
   return 0;
}

OUTPUT
c=1
c=2
c=3

Explanation: In the above program, the class number has one static data variable c. The count( ) is a member functions increment value of static member variable c by one when called. The statement int number :: c=0 initializes the static member with 0. It is also possible to initialize the static data members with other values. In the function main( ), a, b and c are three objects of class number. Each object calls the function count( ). At each call to the function count( ) the variable c gets incremented and the cout statement displays the value of variable c. The objects a, b and c share the same copy of static data member c.

6.13 Write a program to show difference between static and non-static member variables.

# include <iostream.h>
# include <conio.h>


class number
{
       static  int c;             // static variable
       int k;                    // non-static variable


  public:


void zero( )
  {
     k=0;
  }

void count( )
  {
     ++c;
     ++k;

     cout <<"\n Value of c = "<<c <<"  Address of c = "<<(unsigned)&c;
     cout <<"\n Value of k = "<<k <<"  Address of k = "<<(unsigned)&k;
  }


};

int number :: c=0;  // initialization  of static member variable

int main( )
{
     number A,B,C;

  clrscr( );

  A.zero( );
  B.zero( );
  C.zero( );

  A.count( );
  B.count( );
  C.count( );

  return 0;
}

OUTPUT
Value of c = 1 Address of c = 11138
Value of k = 1 Address of k = 65524
Value of c = 2 Address of c = 11138
Value of k = 1 Address of k = 65522
Value of c = 3 Address of c = 11138
Value of k = 1 Address of k = 65520

Explanation: This program compares between static and non-static member variables. The class number has two-member variables c and k. The variable c is declared as static and k is a normal variable. The function zero( ) is used to initialize the variable k with zero. The static member variable c is initialized with zero as shown below:

int number :: c=0; // initialization of static member variable

The function count( ) is used to increment values of c and k. In function main( ), A, B and C are objects of class number. The function zero( ) is invoked three times by object A, B and C. Each object has its own copy of variable k and hence, each object invokes the function zero( ) to initialize its copy of k. The static member variable c is common among the objects A, B and C. Hence, it is initialized only once. Figure 6.7 shows the object and member variables in memory.

Fig.6.7 Static and non-static members

6.14 Write a program to enter a number. Count the total number of digits from 0 to 9 occurring from 1 to entered number.

# include <iostream.h>
# include <conio.h>


class digit
{
static int num[10];
public :


   void check(int n);
   void show ( );
   void input( );
   void ini( );
};


int digit :: num[]={0,0,0,0,0,0,0,0,0,0};
	
   void digit :: show( )
   {
     for (int j=0;j<10;j++)
     {
        if (num[j]==0) continue;
        cout <<"\n  Number "<<j <<" occurs " <<num[j] <<" times";
     }
   }


   void digit :: ini( )
   {
   for (int k=0;k<10;k++)
   num[k]=0;
   }


   void digit :: input( )
   {
     int x,y;
     cout <<endl<<"\n Enter a Number : ";
     cin >>y;
     check(y);
   }


   void digit :: check (int u)
   {
   int m;


     while (u!=0)
     {
        m=u%10;
        num[m]++;
        u=u/10;
     }
}


void main( )
{
   clrscr( );
   digit d;

   //d.ini( );
   d.input( );
   d.show( );
}

OUTPUT
Enter a Number : 22151
Number 1 occurs 2 times
Number 2 occurs 2 times
Number 5 occurs 1 times

Explanation: In the above program, the class digit is declared with one static array member num [10] and four member functions check( ), show( ), input( ) and ini( ). The function input( ) reads an integer through the keyboard. The entered number is passed to function check( ). The function check( ) is invoked by function input( ). The function check( ) separates individual digits of the entered number using repetitive modular division and division operation. The separated digits are counted and the count value is stored in the array num[10] according to the element number. The function show( ) displays the contents of array num[]. The function ini( ) is declared and when called, initializes all array elements with zero. In case the array is not declared as static this function is useful. Here, in this program the array is static, hence we initialize it with the statement int digit:: num[]={0,0,0,0,0,0,0,0,0,0}. If this statement is removed, we need to call the function ini( ).

(2) Static Member Functions

Like member variables, functions can also be declared as static. When a function is defined as static, it can access only static member variables and functions of the same class. The non-static members are not available to these functions. The static member function declared in public section can be invoked using its class name without using its objects. The static keyword makes the function free from the individual object of the class and its scope is global in the class without creating any side effect for other part of the program. The programmer must follow the following points while declaring static function:

(1) Just one copy of static member is created in the memory for entire class. All objects of the class share the same copy of static member.

(2) Static member functions can access only static data members or functions.

(3) Static member functions can be invoked using class name.

(4) It is also possible to invoke static member functions using objects.

(5) When one of the objects changes the value of data member variables, the effect is visible to all the objects of the class.

6.15 Write a program to declare static member functions and call them from the main( ) function.

# include <iostream.h>
# include <conio.h>


class bita
{
   private :
   static int c;
   public :


   static void  count( ) {  c++; }


   static void display( )
   {
     cout <<"\nValue of c  : "<<c;
   }


};


int bita  ::c=0;


void main( )
{
   clrscr( );
   bita:: display( );
   bita::count( );
   bita::count( );
   bita::display( );
}

OUTPUT:

Value of c : 0
Value of c : 2

Explanation: In the above program, the member variable c and functions of class bita are static. The function count( ) when called, increases the value of static variable c. The function display( ) prints the current value of the variable c. The static function can be called using class name and scope access operator as per statements given next.

bita::count( );    // invokes count ( ) function
bita::display( );  // invokes display ( ) function

(3) Static Private Member Function

Static member function can also be declared in private section. The private static function must be invoked using static public function. The following program illustrates the point.

6.16 Write a program to define private static member function and invoke it.

# include <iostream.h>
# include <conio.h>

class bita
{
   private :
   static int c;

   static void  count( ) {  c++; }

public:

static void display( )
{
   count( );        // Call to private static member function
   cout <<"\nValue of c  : "<<c;
   }

};

int bita  ::c=0;

void main( )
{
   clrscr( );
   bita:: display( );
   bita::display( );
}

OUTPUT
Value of c : 1
Value of c : 2

Explanation: In the above program, count( ) is a private static member function. The public static function display( ) invokes the private static function count( ). The function display( ) also displays the value of static variable c.

(4) Static Public Member Variable

The static public member variable can also be initialized in function main( ) like other variables. The static member variable using class name and scope access operator can be accessed. The scope access operator is also used when variables of same name are declared in global and local scope. The following program illustrates this:

6.17 Write a program to declare static public member variable, global and local variable with the same name. Initialize and display their contents.

# include <iostream.h>
# include <constream.h>
int c=11;     // global variable


class bita
{
   public:
   static int c;
};


int bita  ::c=22;   // class member variable


void main( )
{
   clrscr( );


   int c=33;       // local variable


cout<<"\nClass member    c = "<<bita::c;
cout <<"\nGlobal variable c = "<<::c;
cout  <<"\nLocal variable  c = "<<c;
}

OUTPUT
Class member c = 22
Global variable c = 11
Local variable c = 33

Explanation: In the above program, the variable c is declared and initialized in three different scopes such as global, local and inside the class. The variable c declared inside is static variable and initialized to 22. The global variable c is initialized to 11 and local variable c is initialized to 33.

Static Member Variable The value of static variable is displayed using variable name preceded by class name and scope access operator as shown in the statement cout<<“\nClass member c = “<<bita::c;.

Global Variable The global variable can be accessed using variable name preceded by scope access operator as shown in the statement cout <<“\nGlobal variable c = “<<::c;.

Local Variable The local variable can be accessed only by putting its name as shown in the statement cout <<“\nLocal variable c = “<<c;.

6.16 STATIC OBJECT

In C, it is common to declare variable static that gets initialized to zero. The object is a composition of one or more member variables. There is a mechanism called constructor to initialize member variables of the object to desired values. The constructors are explained in next chapter. The keyword static can be used to initialize all class data member variables to zero. Declaring object itself as static can do this. Thus, all its associated members get initialized to zero. The following program illustrates the working of static object.

6.18 Write a program to declare static object. Display its contents.

# include <iostream.h>
# include <constream.h>


class bita
{
    private:
    int c;
    int k;


  public :


  void  plus( )
  {
    c+=2;
    k+=2;
  }


  void show( )
  {
    cout <<" c= "<<c<<"\n";
   
    cout <<" k= "<<k;
  }


};



void main( )
{
    clrscr( );
    static bita A;


    A.plus( );
    A.show( );
}

OUTPUT
c= 2
k= 2

Explanation: The class bita has two-member variables c and k and two member functions plus( ) and show( ). In function main( ), the object A is declared. It is also declared as static. The data member of object A gets initialized to zero. The function plus( ) is invoked, which adds two to the value of c and k. The function displays value of c and k. Declaring objects static, does not mean that the entire class is static including member function. The declaration of static object removes garbage of its data members and initializes them to zero.

6.17 ARRAY OF OBJECTS

Arrays are collection of similar data types. Arrays can be of any data type including user-defined data type, created by using struct, class and typedef declarations. We can also create an array of objects. The array elements are stored in continuous memory locations as shown in Figure 6.8. Consider the following example:

class player
{
private:
   char name [20];
   int age;


public:


   void input (void);
   void display (void);
};

In the example given above player is a user-defined data type and can be used to declare an array of object of type player. Each object of an array has its own set of data variables.

player  cricket[5];
player  football[5];
player  hockey[5];

As shown above, arrays of objects of type player are created. The array cricket[5] contains name, age and information for five objects. The next two declarations can maintain the same information for other players in arrays hockey[5] and football[5]. These arrays can be initialized or accessed like an ordinary array. The program given below describes the working of array of objects.

Fig.6.8 Array of objects

6.19 Write a program to declare array of objects. Initialize and display the contents of arrays.

# include <iostream.h>
# include <constream.h>


class player
{
   private:
   char name [20];
   int age;
   public:
   void input (void);
   void display (void);
};


void player :: input ( )
{
   cout <<"\n Enter Player name : ";
   cin>>name;
   cout <<" Age : ";
   cin>>age;
}


void player :: display ( )

{
   cout <<"\n Player name : "<<name;
   cout <<"\n Age         : "<<age;
}


int main( )
{
   clrscr( );


   player cricket[3];  // array of objects


   cout <<"\n Enter Name and age of 3 players ";
   for (int i=0;i<3;i++)
   cricket[i].input ( );


   for (i=0;i<3;i++)
   cricket[i].display ( );


   return 0;
}

OUTPUT
Enter Name and age of 3 players
Enter Player name : Sachin
Age : 29

Enter Player name : Rahul
Age : 28

Enter Player name : Saurav
Age : 30

Player name : Sachin
Age : 29
Player name : Rahul
Age : 28
Player name : Saurav
Age : 30

Explanation: In the above program, the member function input( ) reads information of players. The display( ) function displays information on the screen. In function main( ), the statement player cricket[3]; creates an array cricket[3] of three objects of type player. The for loops are used to invoke member functions input( ) and display( ), using array of objects.

6.18 OBJECTS AS FUNCTION ARGUMENTS

Similar to variables, objects can be passed on to functions. There are three methods to pass an argument to a function as given below:

(a) Pass-by-value—In this type a copy of an object (actual object) is sent to function and assigned to object of callee function (Formal object). Both actual and formal copies of objects are stored at different memory locations. Hence, changes made in formal objects are not reflected to actual objects.

(b) Pass-by-reference — Address of object is implicitly sent to function.

(c) Pass-by-address — Address of the object is explicitly sent to function.

In pass by reference and address methods, an address of actual object is passed to the function. The formal argument is reference pointer to the actual object. Hence, changes made in the object are reflected to actual object. These two methods are useful because an address is passed to the function and duplicating of object is prevented.

The examples given below illustrate both methods of passing objects to the function as an argument.

6.20 Write a program to pass objects to the function by pass-by-value method.

# include <iostream.h>
# include <conio.h>


class life
{
  int mfgyr;
  int expyr;
  int yr;
  public :


     void getyrs( )
     {
       cout <<"\nManufacture Year : ";
       cin  >>mfgyr;
       cout <<"\n Expiry  Year    : ";
       cin  >>expyr;
     }


     void period ( life);

     };


     void life :: period (life y1)
     {
       yr=y1.expyr-y1.mfgyr;
       cout <<"Life of the product  : " <<yr <<" Years";
     }


void main( )
{
     clrscr( );
     life a1;
     a1.getyrs( );
     a1.period(a1);
}

OUTPUT:
Manufacture Year : 1999
Expiry Year : 2002
Life of the product : 3 Years

Explanation: In the above program, the class life is declared with three member integer variables. The function getrys( ) reads the integers through the keyboard. The function period( ) calculates the difference between the two integers entered. In function main( ), a1 is an object to the class life. The object a1 calls the function getyrs( ). Immediately after this, the same object (a1) is passed to the function period( ). The function period( ) calculates the difference between two integers (dates) using the two data members of the same class. Thus, an object can be passed to the function. To pass an object by reference, the prototype of function period( ) should be as follows:

void period( life &);

6.21 Write a program to pass objects to the function pass-by-address method.

# include <iostream.h>
# include <conio.h>


class life
{
   int mfgyr;
   int expyr;
   int yr;
   public :

void getyrs( )
{
   cout <<"\nManufacture Year : ";
   cin  >>mfgyr;
   cout <<"\n Expiry Year    : ";
   cin  >>expyr;
}


   void period ( life*);
};


void life :: period (life *y1)
{
   yr=y1->expyr-y1->mfgyr;
   cout <<"Life of the product  : " <<yr;
}


void main( )
{
   clrscr( );
   life a1;
   a1.getyrs( );
   a1.period(&a1);
}

OUTPUT:
Manufacture Year : 1999
Expiry Year : 2002
Life of the product : 3 Years

Explanation: The above program is same as the previous one. In this program, the object a1 is passed by address. Consider the following statements:

(a) void period ( life*);
(b) a1.period (&a1);
(c) Yr=y1->expyr-y1->mfgyr;

The statement (a) is the prototype of function period( ). In this statement, the deference operator (*) indicates that the function will accept address of the actual argument. The statement (b) is used to pass the address of the argument to the function period( ). The statement (c) is used to access the member variables of the class. When an object is a pointer to the class members, then its elements are accessed by using -> (arrow) operator. In such case use of dot operator(.) is invalid.

6.19 friend FUNCTIONS

The central idea of encapsulation and data hiding concept is that any non-member function has no access permission to the private data of the class. The private members of the class are accessed only from member functions of that class. Any non-member function cannot access the private data of the class.

C++ allows a mechanism, in which a non-member function has access permission to the private members of the class. This can be done by declaring a non-member function friend to the class whose private data is to be accessed. Here friend is a keyword. Consider the following example:

class ac
{  private:
   char name [15];
   int acno;
   float bal;
   public:
   void read( );
friend void showbal( );
};

The keyword friend must precede the function declaration whereas function declarator must not. The function can be defined at any place in the program like normal function. The function can be declared as friend function in one or more classes. The keyword friend or scope access operator must not precede the definition of friend function. The declaration of friend function is done inside the class in private or public part and a function can be declared as friend function in any number of classes. These functions use objects as arguments. Let us see the statement given below.

(a)  friend void :: showbal (ac a)   // Wrong function definition
   {
      statement1;
      statement2;
   }

The above declaration of function is wrong because the function declarator precedes the keyword friend:

The friend functions have the following properties:

(a) There is no scope restriction for the friend function; hence they can be called directly without using objects.

(b) Unlike member functions of class, friend function cannot access the member directly. On the other hand, it uses object and dot operator to access the private and public member variables of the class.

(c) By default, friendship is not shared (mutual). For example, if class X is declared as friend of Y, this does not mean that Y has privileges to access private members of class X.

(d) Use of friend functions is rarely done, because it violates the rule of encapsulation and data hiding.

(e) The function can be declared in public or private sections without changing its meaning.

6.22 Write a program to access private data using non-member function. Use friend function.

# include <iostream.h>
# include <conio.h>


class  ac
{
   private:
   char name[15];
   int  acno;
   float bal;


public:


void read( )
{
   cout <<"\nName       :" ;
   cin >>name;
   cout <<"\nA/c No. :";
   cin >>acno;
   cout <<"\n Balance   :";
   cin >>bal;
}


friend  void showbal(ac );   // friend function declaration
};


void showbal (ac a)
{
   cout <<"\n Balance of A/c no. " <<a.acno <<" is Rs." <<a.bal;
}


int main( )
{
   ac k;
   k.read( );
   showbal(k);   // call to friend function
   return 0;
}

OUTPUT:
Name      :Manoj

A/c No.    :474

Balance    :40000

Balance of A/c no. 474 is Rs.40000

Explanation: In the above program, class ac is declared. It has three member variables and one member function. Also, inside the class ac, showbal( ) is a function, which is declared as friend of the class ac. Once the outside function is declared as friend to any class, it gets an authority to access the private data of that class. The function read( ), reads the data through the keyboard such as name, account number and balance. The friend function showbal( ) displays balance and acno.

6.23 Write a program to declare friend function in two classes. Calculate the sum of integers of both the classes using friend sum( ) function.

# include <iostream.h>
# include <conio.h>


class first;


      class second
      {
        int s;


        public :


      void getvalue( )
      {
        cout <<"\nEnter a  number : ";
        cin >>s;
      }


friend void sum (second, first);


};


class first
{
	
   int f;
   public :


void getvalue( )
{
      cout <<"\nEnter a  number : " ;
      cin >>f;
}


friend void sum (second , first);
};


      void sum (second d, first t)
      {
        cout <<"\n Sum of two numbers : " <<t.f + d.s;
      }


void main( )
{
   clrscr( );
   first a;
   second b;
   a.getvalue( );
   b.getvalue( );
   sum(b,a);
}

OUTPUT :
Enter a number : 7

Enter a number : 8

Sum of two numbers : 15

Explanation: In the above program, two classes first and second are declared with one integer and one member function in each. The member function getvalue( ) of both classes reads integers through the keyboard. In both the classes, the function sum( ) is declared as friend. Hence, this function has an access to the members of both the classes. Using sum( ) function, addition of integers is calculated and displayed.

6.24 Write a program to exchange values between two classes. Use friend functions.

# include <iostream.h>
# include <conio.h>


class second;


class first
{
      int j;


      public:
      void input( )
      {
      cout <<"Enter value of j : ";
      cin  >>j;
      }


      void show (void)
      {
      cout <<"\n Value of J = ";
      cout <<j <<"\n";
      }
      friend void change (first &, second &);
};



      class second
      {
      int k;
      public :
      void input( )
      {
      cout <<"\nEnter value of k : ";
      cin >>k ;
      }


      void show (void)
      {
      cout <<" Value of K = ";
	
      cout <<k ;

      }
      friend void change (first & , second &);
      };

void change ( first &x, second &y)
{
   int tmp=x.j;
   x.j=y.k;
   y.k=tmp;
}

main( )
{
   clrscr( );
   first c1;
   second c2;
   c1.input( );
   c2.input( );
   change (c1,c2);
   cout <<"\nAfter change values are" <<"\n";
   c1.show( );
   c2.show( );
   return 0;
}

OUTPUT:
Enter value of j : 4

Enter value of k : 8

After change values are

Value of J = 8
Value of K = 4

Explanation: In the above program, two classes first and second are defined. Each class contains one-integer variable and two member functions. The function input( ) is used to read an integer through the keyboard. The function show( ) is used to display the integer on the screen. The function change( ) is declared as friend function for both the classes. Passing values by reference of member variables of both the classes, values are exchanged.

6.25 Write a program to declare three classes. Declare integer array as data member in each class. Perform addition of two data member arrays into array of third class. Use friend function.

# include <iostream.h>
# include <conio.h>

class B;
class C;

      class A
      {
        int a[5];
        public :
        void input( );
        friend C sum (A,B,C);
      };

      void A :: input( )
      {
        int k;
        cout <<"\n Enter five integers : ";
        for (k=0;k<5;k++)
        cin>>a[k];
      }

      class B
      {
        int b[5];
        public :
        void input( );
        friend C sum (A,B,C);
      };

      void B:: input( )
      {
        int k;
        cout <<"\n Enter five integers : ";
        for (k=0;k<5;k++)
        cin>>b[k];
      }

      class C
      {
        int c[5];
        public :
        void show ( );
        friend C sum  (A,B,C);
};

      void C :: show( )
      {
        cout <<"\n\t Addition    : ";
        for (int k=0;k<5;k++)
        cout <<" " <<c[k];
      }

      C sum (A a1 ,B b1, C c1)
      {
        for (int k=0;k<5;k++)
        c1.c[k]=a1.a[k]+b1.b[k];
        return c1;
      }

void main( )
{
   clrscr( );
   A a;
   B b;
   C c;

   a.input( );
   b.input( );
   c=sum(a,b,c);
   c.show( );
}

OUTPUT
Enter five integers : 5 4 8 7 5

Enter five integers : 2 4 1 2 3

Addition    : 7 8 9 9 8

Explanation: In the above program, three classes A, B and C are declared. Each class contains single integer array as data member. They are a[5], b[5] and c[5] respectively. Classes A and B contain member function input( ) to read integers. The function sum( ) is declared as friend in all the three classes. This function performs addition of arrays of class A and B and stores results in the array of class C. The result obtained is returned in main( ) where the return value is assigned to object c. In main ( ) a, b and c are objects of classes A, B and C respectively. The member function show( ) of class C displays the contents of object c.

friend Classes

It is possible to declare one or more functions as friend functions or an entire class can also be declared as friend class. When all the functions need to access another class in such a situation we can declare an entire class as friend class. The friend is not transferable or inheritable from one class to another. Declaring class A to be a friend of class B does not mean that class B is also a friend of class A i.e., friendship is not exchangeable. The friend classes are applicable when we want to make available private data of a class to another class.

6.26 Write a program to declare friend classes and access the private data.

# include <iostream.h>
# include <constream.h>
class B;


class A
{
   private :
   int a;
   public :
   void aset( ) {a=30;}
   void show (B);
};


class B
{
   private :
   int b;
   public :
   voidb_set( )   { b=40 ;};
   friend void A :: show (B bb);
};


void A :: show (B b)

{
   cout <<"\n a = "<<a;
   cout <<"\n b = "<<b.b;
}


void main( )
{
   clrscr( );
   A a1;
   a1.aset( );
   B b1;
   b1.bset( );
   a1.show(b1);
}

OUTPUT
a = 30
b = 40

OUTPUT

a = 30
b = 40

Explanation: In the above program, two classes A and B are declared. Here, class A is a friend of class B. The member function of class A can access the data of class B. Thus, the show( ) function displays the values of data members of both the classes.

6.20 THE const MEMBER FUNCTION

The member functions of a class can also be declared as constant using const keyword. The constant functions cannot modify any data in the class. The const keyword is suffixed to the function prototype as well as in function definition. If these functions attempt to change the data, compiler will generate an error message.

6.27 Write a program to declare const member function and attempt any operation within it.

# include <iostream.h>
# include <conio.h>


      class A

  {
     int c;
     public :


     void add (int a,int b) const
     {
     // c=a+b;          // invalid statement
     a+b;
     cout <<"a+b = "<<_AX ;
  }
};


  int main( )
  {
     clrscr( );
     A a;
     a .add(5,7);
     return 0;
}

OUTPUT
a+b = 12

Explanation: In the above program, class A is declared with one member variable c and one constant member function add( ). The add( ) function is invoked with two integers. The constant member function cannot perform any operation. Hence, the expression c=a+b will generate an error. The expression a+b is valid and cannot alter any value. The result obtained from the equation a+b is displayed using CPU register.

6.21 RECURSIVE MEMBER FUNCTION

Like C, C++ language also supports recursive features i.e., function is called repetitively by itself. The recursion can be used directly or indirectly. The direct recursion function calls itself till the condition is true. In indirect recursion, a function calls another function and then the called function calls the calling function. The recursion with member function is illustrated in the following program.

6.28 Write a program to calculate triangular number by creating a member function. Call it recursively.

# include <iostream.h>
# include <conio.h>


class  num

{
public :


tri_num(int m)
   { int f=0;
       if (m==0)
       return(f);
       else
       f=f+m+tri_num(m-1);
       return (f);
   }


};
void main( )
{
   clrscr( );
num a;
int x;
cout <<"\n Enter a number : ";
cin>>x;
cout<<"Triangular number of "<<x<<" is : "<<a.tri_num(x);
}

OUTPUT
Enter a number : 5
Triangular number of 5 is : 15

Explanation: In the above program, the class num is declared with one member function tri_num( ). This function is used to calculate the triangular number of the entered number. The triangular number is nothing but sum from 1 to that number. In function main( ), a number is read through the keyboard and it is passed to function tri_num( ) which is invoked by object a of class num. The function tri_num( ) is invoked and tri_num( ) invokes itself repetitively till the value of m becomes 0. The variable f holds the cumulative total of successive numbers and return( ) statement returns value of f in function main( ), where it displays triangular number on the screen.

6.22 LOCAL CLASSES

When a class is declared inside a function they are called as local classes. The local classes have access permission to global variables as well as static variables. The global variables need to be accessed using scope access operator when the class itself contains member variable with same name as global variable. The local classes should not have static data member and static member functions. If at all they are declared, the compiler provides an error message. The programs given next illustrate the local classes.

6.29 Write a program to define classes inside and outside main( ) function and access the elements.

# include <iostream.h>
# include <conio.h>


class A
{
      private :
      int a;
      public :


      void get( )
      {
       cout <<"\n Enter value for a  :  ";
       cin >>a;
      }


      void show( )
      {  cout <<endl<<" a = " <<a; }
};


main( )
{
      clrscr( );


      class  B
      {
       int b;
       public :


      void get( )
      {
       cout <<"\n Enter value for b  :  ";
       cin >>b;
      }


      void show( )
      {
       cout <<" b = " <<b;

      }
};


      A j;
      B k;


      j.get( );
      k.get( );
      j.show( );
      k.show( );
      return 0;
}

OUTPUT
Enter value for a : 8

Enter value for b : 9

a = 8 b = 9

Explanation: In the above program, class A is declared before main( ) function as usual. Class B is declared inside the main( ) function. Both the functions have two member functions, get( ) and show( ). The get( ) function reads integers through the keyboard. The show( ) function displays the values of data members on the screen.

6.30 Write a program to declare global variables, read and display data using member functions.

# include <iostream.h>
# include <conio.h>


int j, k, l, m; // global variable


class A
{
      private :
      int a;
      int j;
      public :


      void get( )

      {
       cout <<"\n Enter value for a,j,j and k : ";
       cin >>a >>j>>::j >>k;
      }


      void show ( )
      {
       cout <<endl<<"a= "<<a<<" j="<<j <<"::j="<<::j <<"k="<<k ;
      }
};


int main( )
{
      clrscr( );


      class  B
      {
       int b;
       int l;
       public :


      void get( )
      {
       cout <<"\n Enter value for b,l,l and m : ";
       cin >>b >>l>>::l>>m;
      }


      void show( )
      {
       cout <<"\n b = " <<b <<" l = "<<l <<" ::l = "<<::l <<" m = "<<m;
      }
};


      A x;
      B y;


      x.get( );
      y.get( );
      x.show( );
      y.show( );

return 0;
}

OUTPUT
Enter value for a,j,j and k : 1 2 3 4

Enter value for b,l,l and m : 5 6 4 3

a = 1 j = 2 ::j = 3 k = 4
b = 5 l = 6 ::l = 4 m = 3

Explanation: The above program is same as the previous one. In addition, in this program global variables j, k, l, and m are declared. The member functions get( ) and show( ) read and display values of member variables as well as global variables. Here, both the classes contain a single data member variable with same name as global variables. Thus, to access the global variable where ever necessary, scope access operator is used.

6.23 EMPTY, STATIC AND CONST CLASSES

The classes without any data members or member functions are called as empty classes. These types of classes are not frequently used. The empty classes are useful in exception handling. The syntax of empty class is as follows:

Empty Classes

  class nodata {   };
  class vacant  {  };

We can also precede the declaration of classes by the keywords static, const, volatile etc. But there is no effect in the class operations. Such declaration can be done as follows:

Classes and other keywords

   static class boys {   };
   const class data { };
   volatile class area{ };

6.24 MEMBER FUNCTIONS AND NON-MEMBER FUNCTIONS

So far we have used non-member function main( ) for declaring objects and calling member functions. Instead of main( ) other non-member functions can also be used. The member function can also invoke non-member function and vice versa. When a member function calls to non-member function, it is necessary to put its prototype inside the calling function or at the beginning of the program. It is a better practice to put prototype at the beginning of the program. It is also possible to put definition of the non- member function before class declaration. This method allows member function to invoke outside non-member function without the need of prototype declaration. But this approach creates problem when an outside non-member function attempts to invoke member function.

We know that member functions can be called using object of that class. If a non-member function is defined before class declaration, it is not possible to create object in that function. Hence, the best choice is to put prototype of the non- member function at the beginning of the program that makes easy for both non-member functions and member functions to call each other. The following program explains practically whatever we learned about member function and non- member function in this section.

6.31 Write a program to call a member function using non-member function.

# include <iostream.h>
# include <conio.h>


void moon(void);            // Function prototype declaration


   class mem
   {
       public :


       void earth ( ) {   cout <<"On earth";  }
};


void main ( )
{
   clrscr( );
   mem k;
   moon( );
}



void moon( )
{
   mem j;
   j. earth( );
   cout <<endl<<"On moon  ";
}

OUTPUT
On earth
On moon

Explanation: In the above program, moon( ) is a non-member function and its prototype is declared at the beginning of the program. The function main( ) calls the function moon( ). In function moon( ), object j of type class mem is declared and a member function earth( ) is invoked. Thus, non-member function calls the member function.

6.25 THE main( ) AS A MEMBER FUNCTION

We know that the function main( ) is the starting execution point of every C/C++ program. The main( ) can be used as a member function of the class. But the execution of program will not start from this member function. The compiler treats member function main( ) and the user-defined main( ) differently. No ambiguity is observed while calling a function. The following program narrates this concept:

6.32 Write a program to make main( ) as a member function.

# include <conio.h>
# include <iostream.h>


class A
{
   public:


   void main( )
   {
   cout <<endl<<"In member function main( )";
   }
};


void main( )
{
   clrscr( );
   A *a;
   a->main( );
}

OUTPUT

In member function main( )

Explanation: In the above program, class A is declared and has one member function main( ). In the non-member function main( ), the object a invokes the member function main( ) and a message is displayed as shown in the output.

6.26 OVERLOADING MEMBER FUNCTIONS

Member functions are also overloaded in the same fashion as other ordinary functions. We learned that overloading is nothing but one function is defined with multiple definitions with same function name in the same scope. The program given below explains the overloaded member function.

6.33 Write a program to overload member function of a class.

# include <iostream.h>
# include <stdlib.h>
# include <math.h>
# include <conio.h>


class absv
{
   public :
   int num(int);
   double num (double);


};


int absv:: num(int x)
{
   int ans;
   ans=abs(x);
   return (ans);
}


double absv :: num(double d)
{
   double ans;
   ans=fabs(d);
   return(ans);
}


int main( )
{
   clrscr( );
   absv n;
   cout <<"\n Absolute value of -25 is  "<<n.num(-25);
   cout <<"\n Absolute value of -25.1474 is  "<<n.num(-25.1474);
   return 0;
}

OUTPUT
Absolute value of -25 is 25
Absolute value of -25.1474 is 25.1474

Explanation: In the above program, the class absv has member function num( ). The num( ) function is overloaded for integer and double. In function main( ), the object n invokes the member function num( ) with one value. The compiler invokes the overloaded function according to the value. The function returns the absolute value of the number.

6.27 OVERLOADING main( ) FUNCTION

In the last two subtitles we learnt how to make main( ) as member function and how to overload member function. Like other member function, main( ) can be overloaded in the class body as a member function. The following program explains this concept.

6.34 Write a program to declare main( ) as a member function and overload it.

# include <conio.h>
# include <iostream.h>


class A
{
   public:


   void main(int i)
   {
      cout <<endl<<"In main (int) :"<<i;
   }


   void main (double f)
   {
      cout <<"\nIn main(double) :"<<f;
   }


   void main(char *s)
   {
      cout <<endl<<"In main (char ) : "<<s;
   }


};


void main( )
{
   clrscr( );
   A *a;
   a->main(5);

   a->main(5.2);
   a->main("C++");
}

OUTPUT
In main (int) :5
In main(double) :5.2
In main (char ) : C++

Explanation: This program is same as the last one. Here, the main( ) function is used as a member function and it is overloaded for integer, float and character.

It is not possible to overload the non-member main( ) function, which is the source of C/C++ program and hence the following program will not be executed and displays the error message “Cannot overload ‘main’.

# include <iostream.h>


void main( )
{  }
main (float x, int y)
{
   cout <<x<<y;
   return 0;
}

The main( ) is the only function that cannot be overloaded.

6.28 THE main ( ), MEMBER FUNCTION AND INDIRECT RECURSION

When a function calls itself then this process is known as recursion or direct recursion. When two functions call each other repetitively, such type of recursion is known as indirect recursion. Consider the following program and explanation to understand the indirect recursion using OOP. The program without using OOP is also described for the sake of C programmers and those who are learning C++.

6.35 Write a program to call function main( ) using indirect recursion. // Indirect Recursion Using OOP //

# include <iostream.h>
# include <conio.h>


int main (int);


class rec

{
   int j;
   public:
   int f;


   rec (int k, int i)
   {
       clrscr( );
       cout<<"[ ";
       f=i;
       j=k;
}


   ~rec ( )
   {  cout <<"\b\b] Factorial of number : "<<f ; }



void pass( )
{
   cout<<main (j--)<<" * ";
}


};


rec a(5,1);


main(int x)
{
   if (x==0)
   return 0;


   a.pass( );
   a.f=a.f*x;
   return x;
}

OUTPUT
[ 0 * 1 * 2 * 3 * 4 * 5 ] Factorial of number : 120

Explanation: In the above program, class rec is declared with constructor, destructor, member function pass( ) and two integer variables. The integer variable j is private and f is public. The function main( ) is defined with one integer argument. Usually, main( ) with arguments is used for the applications used on the dos prompt. In this program, main( ) is called recursively by member function pass( ). When a function call is made, the value of member data variable is decreased first and then passed. Thus, the main( ) passes value to itself. In function pass( ), main( ) function is invoked and its return value is displayed. The public data member is directly used and by applying multiplication operation, factorial of a number is calculated.

Generally, objects are declared inside the function main( ). But in this program, function main( ) is used in recursion. Hence, if we put the object declaration statement inside the main( ), in every call of main( ) object is created and the program does not run properly. To avoid this, the object is declared before main( ).

Constructor is used to initialize data members as well as to clear the screen. Destructor is used to display the factorial value of the number. All the statements that we frequently put in main( ) are written outside the main( ).

Before the class declaration, prototype of main( ) is given and this is because the member functions don't know about main( ) and the prototype declaration provides information about main( ) to member function.

For C programmers the above program in C style is explained below.

6.36 Write a program to call function main( ) using indirect recursion in C style. // Indirect Recursion in C style //

# include <iostream.h>
# include <conio.h>
# include <process.h>


int m=5;
int f=1;
int j;
main (int x)
{


   void  pass (void);


      if (x==0)
      {  clrscr( );
         cout <<endl<<"Factorial of number ="<<f;
         return 0;
      }
   f=f*x;
   pass( );

   return x;
}


void pass ( ) { main (m--); }

OUTPUT
Factorial of number =120

Explanation: The logic of the program is same as the last one. The user-defined function pass( ) has only one job i.e., to invoke function main( ). The if conditions inside main( ), checks the value of variable x. If value of x is zero, the if block is executed that displays factorial of the number and terminates the program.

6.29 BIT FIELDS AND CLASSES

Bit field provides exact amount of bits required for storage of values. If a variable value is 1 or 0, we need a single bit to store it. In the same way if the variable is expressed between 0 and 3, then two bits are sufficient for storing these values. Similarly if a variable assumes values between 0 and 7 then three bits will be enough to hold the variable and so on. The number of bits required for a variable is specified by non-negative integer followed by colon.

To hold the information we use the variables. The variables occupy minimum one byte for char and two bytes for integer. Instead of using complete integer if bits are used, space of memory can be saved. For example, to know the information about vehicles, following information has to be stored in the memory.

(1) PETROL VEHICLE

(2) DIESEL VEHICLE

(3) TWO-WHEELER VEHICLE

(4) FOUR-WHEELER VEHICLE

(5) OLD MODEL

(6) NEW MODEL

In order to store the status of the above information, we may need two bits for type of fuel as to whether vehicle is of petrol or diesel type. Three bits for its type as to whether the vehicle is two or four-wheeler. Similarly, three bits for model of the vehicle. Total bits required for storing the information would be 8 bits i.e., 1 byte. It means that the total information can be packed into a single byte. Eventually bit fields are used for conserving the memory. The amount of memory saved by using bit fields will be substantial which is proved from the above example.

However, there are restrictions on bit fields when arrays are used. Arrays of bit fields are not permitted. Also the pointer cannot be used for addressing the bit field directly, although use of the member access operator (->) is acceptable. The unnamed bit fields could be used for padding as well as for alignment purposes.

(1) Bits fields should have integral type. A pointer array type is now allowed.

(2) Address of bit fields cannot be obtained using & operator.

The class for the above problem would be as follows:

class vehicle
{
   unsigned type: 3;
   unsigned fuel: 2;
   unsigned model: 3;
};

The colon(:)in the above declaration tells to the compiler that bit fields are used in the class and the number after it indicates how many bits are required to allot for the field. Simple program is illustrated below.

6.37 Write a program to use bit fields with classes and display the contents of the bit fields.

# include <conio.h>
# include <iostream.h>


# define PETROL 1
# define DIESEL 2
# define TEO_WH 3
# define FOUR_WH 4
# define OLD  5
# define NEW  6


      class vehicle
      {
        private :
        unsigned type : 3;
        unsigned fuel : 2;
        unsigned model :3;


      public :


      vehicle ( )
      {
        type=FOUR_WH;
        fuel=PETROL;
        model=NEW;
      }


      void show ( )
      {
      if (model==NEW)

      cout <<"\n     New Model ";
      else
      cout <<"\n     Old Model ";


      cout <<"\n Type of Vehicle : "<< type;
      cout <<"\n Fuel            : "<<fuel;
      }
};


void main( )
{
      clrscr( );


      vehicle v;
      cout<<" Size of Object  : "<<sizeof(v)<<endl;
      v.show( );
}

OUTPUT
Size of Object : 1

   New Model
Type of Vehicle : 4
Fuel            : 1

Explanation: In the above program, using # define macros are declared. The information about the vehicle is indicated between integers 1 to 6. The class vehicle is declared with bit fields. The number of bits required for each member is initialized. As per the program, type of vehicle requires 3 bits, fuel requires 2 bits and model requires 3 bits. An object v is declared. The constructor initializes bit fields with data. The output of the program displays integer value stored in the bit fields, which can be verified with macro definitions initialized at the beginning of the program.

SUMMARY

(1) A class in C++ is similar to structure in C. Using class or structure, a programmer can merge one or more dissimilar data types and a new custom data type can be created.

(2) In C++, classes and structures contain member variables and member functions in their declarations with private and public access blocks that restrict the unauthorized use. The defined classes and structures further can be used as custom data type in the program to declare objects.

(3) In C++ private and public are two new keywords. The private keyword is used to protect specified data and functions from illegal use whereas the public keyword allows access permission.

(4) The member function can be defined as (a) private or public (b) inside the class or outside the class.

(5) To access private data members of a class, member functions are used.

(6) The difference between member function and normal function is that the normal can be invoked freely whereas the member function can be invoked only by using the object of the same class.

(7) static is the keyword used to preserve value of a variable. When a variable is declared as static, it is initialized to zero. A static function or data element is only recognized inside the scope of the present class.

(8) When a function is defined as static, it can access only static member variables and functions of the same class. The static member functions are called using its class name without using its objects.

(9) The member functions of a class can also be declared as constant using const keyword. The constant functions cannot modify any data in the class.

(10) An object of a class can be passed to the function as arguments like variables of other data type. When an object is passed by value then this method is called as pass by value whereas when reference of an object is passed to the function then this method is called as pass by reference.

(11) When a class is declared inside the function such classes are called as local classes. The local classes have access permission to global variables as well as static variables. The local classes should not have static data members and functions.

EXERCISES

[A] Answer the following questions.

(1) Explain class and struct with their differences.

(2) Which operators are used to access members?

(3) Explain the uses of private and public keywords. How are they different from each other?

(4) Explain features of member functions.

(5) What are static member variables and functions?

(6) How are static variables initialized? Explain with the statement.

(7) What are friend functions and friend classes?

(8) How are static functions and friend functions invoked?

(9) What do you mean by constant function?

(10) What are local classes?

(11) What is recursion?

(12) What are bit fields?

(13) List the keywords terminated by colon with their use.

(14) Can member functions be private?

(15) What is the concept of data hiding? What are the advantages of its applications?

(16) Is it possible to access private data members without using member function? If yes, explain the procedure with an example.

(17) What are static objects?

(18) What is the difference between object and variable?

[B] Answer the following by selecting the appropriate option.

(1) The members of a class are by default

(a) private

(b) public

(c) protected

(d) none of the above

(2) The members of struct are by default

(a) public

(b) private

(c) protected

(d) none of the above

(3) The private data of any class is accessed by

(a) only public member function

(b) only private member function

(c) both (a) and (b)

(d) none of the above

(4) When the class is declared inside the function, it is called as

(a) local class

(b) global class

(c) both (a) and (b)

(d) none of the above

(5) A non-member function that can access the private data of class is known as

(a) friend function

(b) static function

(c) member function

(d) library function

(6) Encapsulation means

(a) protecting data

(b) allowing global access

(c) data hiding

(d) both (a) and (c)

(7) The size of object is equal to

(a) total size of member data variables

(b) total size of member functions

(c) both (a) and (b)

(d) none of the above

(8) In the prototype void sum( int &); arguments are passed by

(a) value

(b) reference

(c) address

(d) none of these

[C] Attempt the following programs.

(1) Write a program to declare a class with three integer public data variables. Initialize and display them.

(2) Write a program to declare private data member variables and public member function. Read and display the values of data member variables.

(3) Write a program to declare private data member and a function. Also declare public member function. Read and display the data using private function.

(4) Write a program to declare three classes S1, S2, and S3. The classes have a private data member variable of character data type. Read strings for the classes S1 and S2. Concatenate the strings read and assign it to the data member variable of class S3.

(5) Write a program to enter positive and negative numbers. Enter at least 10 numbers. Count the positive and negative numbers. Use classes and objects.

(6) Write a program to declare class with private member variables. Declare member function as static. Read and display the values of member variables.

(7) Write a program to declare a class temp_ture as given below. Declare array of 5 objects. Read and display the data using array.

class  temp_ture
{
     private:
     char date[12],  ct1[15], ct2[15], ct3[15],  ct4[15];
     int temp [4]
}

(8) Write a program to declare a class with two integers. Read values using member function. Pass the object to another member function. Display the differences between them.

(9) Write a program to define three classes. Define a friend function. Read and display the data for three classes using common functions and friend functions.

(10) Write a program to define a local class. Also define global variables with the same name as that of member variables of class. Read and display the data for global and member variables.

(11) Write a program to generate fibonacci series using recursion with member function.

(12) Write a program to overload member function and display string, int and float using overloaded function.

(13) Write a program to calculate sum of digits of entered number using indirect recursion. Recursion should be in between main( ) and member function.

(14) Write a program to display string in reverse using recursion.

(15) Write a program to count number of vowels present in the entered string.

(16) Write a program to find largest out of ten numbers.

(17) Write a program to count numbers between 1 to 100, which are not divisible by 2, 3 and 5.

[D] Trace the bugs in the following programs.

(1)

class data
{
private ;
};

(2)

class data
{
private:
int x=20;
}

(3)

# include <iostream.h>
# include <conio.h>

class  data
{  int x; };

void main( )
{  data A;
   A.x=30;  }

(4)

# include <iostream.h>
# include <conio.h>

class  data
{    int x;
     public:
     void show (void);
};
void show ( ) {  cout <<"\n In show ( )"; }

void main( )
{    data A;
     A.show ( ); }