OOP - Lab Manual
OOP - Lab Manual
Lab Rubrics
CLO’s PLO’s
Preface
L earning is a process that requires class instructions and practice labs. If we omit any of
the above then the learning process is clearly flawed. This book is an attempt to standardize
the lab instructions through the development of a lab curriculum that is based on the class
curriculum. This document is intended to be used by lab instructors, course
instructors and students.
The intent of this curriculum is to define a clear lab structure that can be followed by
the lab instructor and the students. In the absence of such curriculum the labs are often run
without any formal structure. Another problem is that there is no grading criteria defined for
each lab which leads to unethical practices. Perhaps one of the greatest problems faced by lab
instructors is that they are unable to keep the students occupied for the entire duration of the
lab due to which the learning process is greatly hampered.
The labs have been developed in a way that there is synchronization between the class
and the lab. The entire book has been divided into 15 labs having duration of 3 hours each.
Students of the course are expected to carefully read the concept map before coming to the
lab. Students come to the lab with a designs/ program that will be handed over to the lab
instructor for further grading. This code/ design is primarily based on previous learning’s and
experiments. Each lab has a detailed walkthrough task which provides a problem statement
and its programmable solution to the students. The students can raise queries about the code
provided and the lab instructor will guide the students on how the solution has been designed.
Thereafter predefined practice questions have been presented such that each question has a
fix duration and grade. Students are graded upon their accomplishments in these practice
tasks. At the end of the lab the lab instructor will assign an unseen task to the students. This
unseen task contains all the concepts taught in the lab. These unseen tasks have a higher level
of complexity and generally have a greater gain in terms of marks.
What sets these labs apart is the fact that a clear grading criteria has been defined for
each lab. Students are aware of the grading criteria and are expected to meet the requirements
for successful completion of each lab.
Lab Manual for Object Oriented Programming
(LAB-01)
Page 1
Lab 1 - Functions and Pointers
1. Introduction
C++ programming that you studied in the previous semester is purely based on writing a set of instructions in a
particular sequence such that the output is based on the sequence of the written statements. If this sequence of
instructions is modified then it could have a large impact on the resulting program. Often a situation arises where we
intend to use a particular chunk of code again and again in a single program. In this scenario using sequential
programming the programmer is forced to copy-paste the code in various locations of the source file.
Although this is a solution, it is not a practical one because it causes the code to become lengthy, unmanaged, poorly
structured and difficult to understand. In such a situation function handling offers an attractive and easy to
implement alternative that is widely accepted and promoted by programmers of all languages.
This lab is a refresher course on the use of functions, pointers and building logic. The functions that are designed
will receive variables and arrays from the user. The function will perform some processing on the provided data and
return results back to the main program.
The importance of this lab can be highlighted through the fact that functions play a pivotal role in the establishment
of classes, objects and their manipulations. A large portion of object oriented programming is based on manipulating
variables using functions. In the later part of this lab the use of pointers has been emphasized. Concepts relating to
pointers, memory access, using arrays with pointers have been presented.
Page 2
Lab 1 - Functions and Pointers
3. Concept Map
Computer programmers have always devised mechanisms through which they can make their code more
understandable and then reusable. In this regard functions offer a very popular and easy mechanism of introducing
the above goals. Function handling operates on the concept of provision of service/ functionality. We can call the
services of a function by providing the required data and in result getting the promised service from the function.
Reusability of code means devising methods through which you can use code again and again without having to
copy-paste in the source file. Modularity of code means dividing the code into small, manageable and easy to
understand segments.
The creation of a function is based on two similar yet distinct statements called a function definition and function
prototype.
A function prototype explains only how a function will be called and what data type it will return. A function
definition on the other hand matches the function prototype and also includes a function body.
For example the following is the function prototype of a function that finds the sum of two integers passed to it:
int c=a+b;
In the following example, variables a and b are parameters of the function addtwo( ).
Page 3
Lab 1 - Functions and Pointers
int c=a+b;
cout<<c;
Now suppose we are calling the same function from within the main().
void main( )
addtwo(3,4);
To increase the practical use of functions, a programmer may want the result of a function to be given back after
processing. This process is called returning a value from a function. It is important to remember that functions can
only return a single value (of any data type). If a function will not return a value then it is necessary to write void
before the function name in the prototype and the definition. It is not necessary for a function to return a value.
For example the following function does not return a value hence the void keyword is used
int c=a+b;
cout<<c;
The following function returns an integer value hence the keyword int is used.
int c=a+b;
return (c);
The value being returned can be displayed by using the following statement from where the function is being called.
Page 4
Lab 1 - Functions and Pointers
cout<<addtwo(x, y);
All the functions we have discussed until now are pass by value. Pass by value is an argument passing technique in
which the function receives a parameter and works with a copy of the value being provided. This means if a change
is made to the parameter value then still no change will not be reflected in the argument.
On the other hand pass by reference is an argument passing technique in which the function works with the exact
variable that is being passed as an argument. This means that even the smallest change in a parameter will be exactly
reflected in the arguments. This further implies that the arguments and the parameters are tightly coupled.
4.6 Pointers
Pointers are special kind of variables that are allowed to hold the address of another variable. Because of their
pointing ability pointers are considered very powerful in C++. Pointers can hold the address of another variable and
this is called referencing the memory location. When we attempt to extract values from a memory location then this
is called dereferencing a pointer.
Page 5
Lab 1 - Functions and Pointers
In the figure provided above there is a pointer variable called “a”. This variable is pointing to the memory address of
variable b. The memory address of variable b is 1008. In this diagram you will also note that the pointer “a” has its
own memory address. This is a very important fact because pointers themselves also require a space in memory.
When we write a code on our compilers remember that every computer has its own memory and the availability of
memory space. Our compilers take the help of a memory manager and allocate space in a memory slot that is
available to the system. This means every time we run the code we may get a different memory allocation.
Consider the code provided below:
Figure 2: The various operations that can be performed with a pointer. Output is also provided. Memory addresses
may be different depending on the hardware environment
In the code above first a simple integer variable is created. Then an integer pointer is created because we intend to
point to an integer variable. The pointer is then given the address of variable x by using the address operator. Then
we use the dereference operator (*) that directs us to the memory location where the pointer is pointing to.
Page 6
Lab 1 - Functions and Pointers
lab instructor.
cylinder is provided. The function should return the value of area. The area of a cylinder is 𝜋 𝑟2 ℎ. Consider the
Practice to Write a program that creates a function to find the area of a cylinder if the radius and height of the
6.1 Tools
Visual Studio 2008.
Page 7
Lab 1 - Functions and Pointers
In the code above note that the two functions use different mechanisms for passing/ using an array. You can choose
the method that suits your code/ situation. The size is passed in both functions because without the size the functions
can easily cross the array bounds. Hence passing the array size is a good practice.
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
Page 8
Lab 1 - Functions and Pointers
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab01
7.5 Outcomes
After completing this lab, students will be able to use functions and also understand the concept of parameters,
arguments and returning of values. Students should also be comfortable with pointers and their use in functions.
Page 9
Lab 1 - Functions and Pointers
7.6 Testing
Test Cases for Practice Task-1
Sample Inputs Sample Outputs
Number: 3 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, …
Number: 5 120
Page 10
Lab Manual for Object Oriented Programming
(LAB-02)
Introduction to Classes and Objects
Page 13
Lab 2 - Introduction to Classes and Objects
Page 14
Lab 2 - Introduction to Classes and Objects
3. Concept Map
4.1 Object
In OOP an object is a very much like a real world object. An object can be defined as a collection of state and
behaviour. For example, consider the example of a cat. A cat is has both a state and behaviour. The state of a cat is
its attributes namely colour, breed, gender, age, weight, height, etc. Whereas the behaviour of a cat is its sound,
eating, sleeping, yawning, walk, etc. Hence a cat can be completely identified by its unique characteristics and
behaviours.
In programming an object is a collection of variables and functions that together have a unique purpose of
identifying a distinctive entity.
Again referring to the concept of an object and the example of a cat. The cat had a number of characteristics or
attributes that can be used to identify a cat. In programming these attributes can be programmed by using regular
variables that are called data members. A class can be composed of a number of data members of various types. The
data members of a class are private by default i.e. they are not directly accessible outside the class.
Here it is important to point out that often people casually refer to these as variables, which is a wrong terminology.
These should only be called data members or class variables.
Again referring to the concept of an object and the example of a cat. The cat had a number of behaviours or things
that a cat does. In programming these behaviours can be programmed by using functions that are called member
functions. A class can be composed of a number of member functions of various types. Overloading of member
functions is also permitted in C++. The implementation section of member functions can be separated whereby the
body of the function is created outside the class but the function prototype has to exist in the body of the class. The
implementation section is separated by writing the return type followed by class name. This is further followed by
scope resolution operator :: and then the remaining function definition.
int memberfun(int);
// Function prototype
};
int myclass :: memberfun (int x)// Note the scope resolution operator
{
...// Function body
}
void main( )
{
Page 15
Lab 2 - Introduction to Classes and Objects
4.5 Class
A class is a collection of data members and member functions. A class is used to define an abstract data type. This
abstract data type is used in the construction of an object which is used to access all the data members and member
functions. A class has to be created before it can be used. Provided below are the syntax for creating a class.
4.6 Encapsulation
Encapsulation is a very important design goal because of which OOP is preferred over conventional programming.
Encapsulation is a quality because of which data and function are stored in a single unit commonly known as a class.
This unit/ bundle ensures that the data is not openly accessible to the outer world. The access is provided by the
functions that are part of the unit/bundle. This means that the functions work like doors in a room. You can prevent
thieves from breaking in. Only those people can enter who come through the door.
Page 16
Lab 2 - Introduction to Classes and Objects
5.2.1 Task-1
Identify the data members and member functions for a pizza class. The class should have all the relevant attributes
and qualities required for a pizza object. Try to be imaginative in your design. For example consider various sizes,
toppings, base thickness, etc.
6.1 Tools
Visual Studio 2008.
Practice to Write a program that creates a class called cylinder. The data members of the class are radius and height
of the cylinder is provided. Write two functions that set the respective values and then write a single constant
function that will read the values.
Page 17
Lab 2 - Introduction to Classes and Objects
Figure 1: Class for creating a cylinder with its relevant data members
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
Page 18
Lab 2 - Introduction to Classes and Objects
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab02
7.4 Outcomes
After completing this lab, students will be able to design a basic class with data members and member functions.
7.5 Testing
Test Cases for Practice Task-1
Sample Inputs Sample Outputs
Set the following values Brand = DELL
Brand = DELL Model = 1565D
Model = 1565D Serial = 123456
Serial = 123456 Colour = Silver
Colour = Silver Price = 64500.5
Price = 64500.5 Processor = 2.8
Processor = 2.8 RAM = 3
RAM = 2 Screen = 15.6
Screen = 15.6
Page 19
Lab 2 - Introduction to Classes and Objects
Length: 4 Length = 5
width: 10 Width = 11
Area = 55
Page 20
call the increment function Check the use of constant function for display
Number: 5 Number = 5
Factorial = 120
Page 22
Lab 3 - Access Specifiers, Constructors and Destructors
1. Introduction
Programming that you studied in the previous semester does not strongly support programming practices like
encapsulation and data hiding. In fact these features are almost nonexistent in sequential programming. Object
Oriented Programming is purely based on these practices and enforces these practices through various techniques. In
this regard access specifiers play a very important role because they are the first line of defence in secure
programming.
This lab is designed to teach three very basic yet essential concepts of OOP namely access specifiers, constructor
and destructors. Access specifiers provide a technique through which we can restrict access to data members and
member functions. After enforcing access it is important to reduce our reliance on too many member functions.
Constructors offer a very attractive and easy to implement technique through which we can take steps call
procedures whenever an object is created. The use of constructors is preferred over the use of member functions
because constructors are called automatically and hence they can invoke further functions whereas simple member
functions have to be called sequentially and explicitly one by one every time an object is created.
Similarly this lab also focuses on the use of destructors that are called whenever an object goes out of scope. In this
the lab the students will be familiarized with the use of access specifiers, constructors and destructors.
Page 23
Lab 3 - Access Specifiers, Constructors and Destructors
3. Concept Map
Access specifier also known as access modifier provides a technique for enforcing access control to class members
(data members and member functions). The use of access specifiers enforces encapsulation and data hiding. C++
provides three access specifiers i.e. public, private and protected. In this lab we will only cover the public and the
private access specifier. The protected specifier is left for future discussions.
The public access specifier is the one that provides unrestricted access to the class members. While the private
access specifier provides a very strict/ restricted access to class members. All the class members that are written
under the public access can be accessed both inside and outside the class without any restriction. On the other hand
all the class members written as private are accessible inside the class but are not accessible outside the class. The
best and most common way of accessing private data members is through the use of a public functions.
When we are discussing access specifiers it must be pointed out that by default classes are private whereas
structures are public. Hence if you do not write private then your listed class members are considered private in a
class.
The correct convention for the use of access specifiers is that data members are kept private whereas functions are
kept public. Hence you are providing a public interface for accessing restricted items in a class.
// This
int myclass :: memberfun (int x) because itsfunction isis
prototype still public
public
{
datamember=x;
}
void main( )
{
myclass obj; myclass::datamember=10; obj.memberfun(10);
} //Syntax Error: private member
4.2 Constructors
A constructor is a function that is automatically called when an object is created. This function can exhibit the
regular behaviour of any function except that it cannot return a value. The reason why constructors are needed is that
unlike regular functions which need to deliberately called, a constructor will be automatically called when an object
is created. Every constructor has a body from where we can call regular member functions.
Page 24
Lab 3 - Access Specifiers, Constructors and Destructors
A very important question which is often asked is that how does the compiler know that the constructor function
needs to be called automatically? The answer is very simple. A constructor is a function that has the same name as
the class. Whenever an object is created the compiler searches for a function having the same name as the class i.e.
the constructor. Given below is a sample code that shows the class constructor. Generally the constructor is defined
as public. Also the constructor can be overloaded like a regular member function. An important point regarding a
constructor is that it cannot return a value. In fact writing the keyword void is strictly prohibited.
void main( )
{
myclass obj;
}
4.3 Destructors
Constructors are designed to help initialize/ create an object. Destructors on the other hand do exactly the opposite.
Destructors are called whenever an object goes out of scope. When this happens it is necessary to perform cleanup
procedures especially when you have used dynamic memory or you have been working with pointers in your code.
The destructor function can be used to free up memory that you have allocated or dereference pointers that were
referenced. The rules for a destructor are as follows:
They have the same name as the class just simply preceded by a tilde (~)
They can take no arguments
They cannot return anything, not even void.
Page 25
Lab 3 - Access Specifiers, Constructors and Destructors
class student
{
int age;
int cnic;
int semester;
char name;
public:
int setall(int a, int c, int s, int sem, char n) const;
{
age=a;
c=cnic;
semester=s;
name=n;
}
}
void main( )
{
Student obj;
obj::setall( );
obj.displayall( );
obj.setage( );
Student anotherobj;
Student::anotherobj::setall( );
}
6.1 Tools
Visual Studio 2008.
Page 26
Lab 3 - Access Specifiers, Constructors and Destructors
class pizza
{
private:
int size, price, thickness;
string topping;
public:
void setsize()
{
cout<<"Enter size of pizza: ";
cin>>size;
}
void setprice()
{
cout<<"Enter price of pizza: ";
cin>>price;
}
void setthickness()
{
cout<<"Enter thickness of pizza: ";
cin>>thickness;
}
void settopping()
{
cout<<"Enter toppings of pizza: ";
cin>>topping;
}
void display() const
{
cout<<"The ordered pizza details are: ";
cout<<"\nSize: "<<size;
cout<<"\nPrice: "<<price; cout<<"\
nTopping:"<<topping; cout<<"\
nThickness:"<<thickness<<"\n";
}
pizza() //class constructor: cannot have a return type
{
setsize();
setprice();
setthickness();
settopping();
}
};
void main()
{
pizza obj;
obj.display( );
}
Page 27
Lab 3 - Access Specifiers, Constructors and Destructors
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab03
LeCream allows its customers to purchase a vanilla wafer with their ice cream. If the customer wants to
purchase the wafer he will have to pay an additional Rs 10. This amount should be added to the total
amount payable by the user.
If the customer asks for chocolate flavour then he will have to pay an additional amount i.e. Rs 120 for two
scoops and Rs 180 for three scopes. Design a function that will be called if the customer chooses flavoured
ice cream.
The program should show a menu that asks the customer for his requirements and then displays the final
payable amount with full details about the flavour, number of scoops and wafer
Page 28
In the end create a class destructor that displays a thank you message to the user.
Design your program using sound OOP practices. Carefully determine the data members, member functions, access
specifiers, activities to be performed in the constructor. Make sure that you use good naming conventions in your
code. A good design can earn you higher marks.
7.2 Outcomes
After completing this lab, students will be able to design a class that correctly implements class members by
observing access specifiers. The students will also be familiar with the use of a constructor and destructor.
7.3 Testing
Test Cases for Practice Task-1
Sample Inputs Sample Outputs
Flavour = chocolate Your choice of ice cream is as follows
Wafer required = yes Flavour = chocolate
Number of scoops = 3 Number of scoops = 3
Wafer is required
Total price is 190
Page 32
Lab Manual for Object Oriented Programming
(LAB-04)
Constructor Overloading and Copy Constructors
Lab 04: Constructor Overloading and Copy
Constructors CLO(2,4)
1. Introduction
In the previous lab a detailed practice session was conducted that focused on access specifiers and constructors.
Constructors are special functions that are automatically called when an object is created. This lab is geared towards
an extended use of constructors through overloading. Another flavour of constructors is the copy constructor which
creates an object by using a previously implemented object. This can be accomplished through the use of a copy
constructor.
3. Concept Map
Function overloading is an advanced concept in modern languages where two function can have the same name. The
question that arises here is that how does a compiler know which function to call. The simple answer is that the
Page 33
function calling is determined based on the type of parameters/ the number of parameters being passed/ order of
parameters being passed. Hence two function can have the same name but there must be a difference in the number
of parameters, type of parameters or the order of parameters. For example in the function prototypes below the
function fun( ) has been overloaded and its different flavours are presented.
Page 34
Lab 4 - Constructor Overloading and Copy Constructors
It is important to highlight here that if two functions have a different return type then it does not mean that they are
overloaded. For a function to be overloaded it is necessary for the function to exhibit changes in the parameters.
example (int on, float th, int tw) //Another overloaded Constructor
: Parameterized ->2
{
...
}
};
int main()
{
example obj;//Creation through nullary constru
example obj2(1, 2, 3.3);//Creation through first parameterized constru example obj3(1
Page 35
Lab 4 - Constructor Overloading and Copy Constructors
example objects that do not use pointers or arrays. Although the default copy constructor will copy any type of
object but it is strongly recommended that the copy constructor be used only for objects that have non pointer data
members. The default copy constructor performs a member by member copy i.e. the copy constructor creates an
exact copy where data members are copied one by one to the new object. Always remember that in copy
constructors the original object is maintained in its original state and the copy changes are only exhibited in the
newly created object. In this lab we will just restrict ourself to the use of the default copy constructor.
The default copy constructor can be explicitly called as follows:
Both statements create an object of the clss class. Of course any of the above statements can be used for copying an
object into another object.
Caution: The copy constructor is always called at the time of creating a new object. If at any time after the creation
of objects you copy contents of one object to the other then the copy constructor is not called. We will discuss more
on this in future lectures.
6.1 Tools
Visual Studio 2008.
Page 36
Lab 4 - Constructor Overloading and Copy Constructors
class student
{
private:
string name;
int age;
public:
Figure 1: The student class demonstrating the use of a parameterized and nullary constructor. Also note the default
copy constructor being used
Page 37
Lab 4 - Constructor Overloading and Copy Constructors
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab04
In the main you will construct three objects that demonstrate the use of the three constructors. After calling the
constructor it will take over and will handover control to the area function, and then the price calculation function.
Remember that the user should not have access to modifying the price.
Determine the access specifiers, data members and member functions. Also note that each constructor can / will
have a distinct functionality in its body. Hence do not try to copy code from one constructor to the other. Focus on
the design clarity and quality of your code.
Page 38
7.2 Practice Task 2 CLO(2,4)
Once you have completed the above task you are also required to use the default copy constructor to show that
values have been copied to the new created object. Use the display( ) function to show the individual objects.
7.3 Outcomes
After completing this lab, students will be able to construct a class object by using parameterized constructors. The
students will also be familiar with the use of a constructor and destructor.
7.4 Testing
Test Cases for Practice Task-1
Sample Inputs Sample Outputs
Using Nullary constructor Your LCD purchase details are:
Length = 48
Length = 48 Width=30
Width = 30
Price=93600
Page 41
Lab Manual for Object Oriented Programming
(LAB-05)
Shallow Copy / Deep Copy
Working with Arrays
Page 42
Lab 5 - Shallow Copy/ Deep Copy, Working With Arrays
1. Introduction
In the previous lab a very basic introduction to copy constructors was presented. The purpose of a copy constructor
is to assist in the creation of exact copy of an object when it is being created. From the perspective of a beginner this
is enough but when we investigate the concept of copying we find that the default copy constructor is not enough.
Hence we need to define our own copy constructor. In this lab the creation of a copy constructor with details about
deep copy and shallow copy will be presented.
Arrays play an important role in any program. Arrays can be used in many forms in OOP for example arrays as data
members, arrays of objects, using static and dynamic arrays and finally the relationing arrays and constructors. All
these aspects of arrays will be discussed in detail in this lab.
3. Concept Map
Although C++ provides you with a basic copy constructor, but still there are occasions when you need to design you
own copy constructor. Given below are some of the reasons why you might want to create a copy constructor.
You need to copy only some of the data members to a new object.
Your objects contain pointers.
Your objects contain dynamic data members.
Page 43
Lab 5 - Shallow Copy/ Deep Copy, Working With Arrays
There may be other numerous reasons why you might want to create a customized copy constructor. Before you
begin you must familiarize yourself with the syntax of a copy constructor. A copy constructor always receives an
object as a parameter and hence we can extract the data from the parameterized object and place the data in the
newly created object. Presented below are the two syntax for copy constructors:
In the above prototypes the object which will be copied is called “other”. By writing the const keyword a copy of an
object can be created without any change to the inherent data members. Although only some of the data members
can be copied.
Page 44
Lab 5 - Shallow Copy/ Deep Copy, Working With Arrays
In the above code when object obj1 is created the nullary constructor is called and hence values 10 and 20 are
allocated to data members a and b respectively. Now when object obj2 is being created obj1 is passed to the copy
constructor as an argument. While creation of obj2 control is never shifted to the basic constructor because we are
attempting to make a new object by copying.
(a)
Memory
Copy of Object 1
Object 1
(b)
Figure 1: The effect of copy constructors on a pointer data member (a) using shallow copy (b) Using deep copy
In the code snippet below a deep copy constructor has been provided that creates a copy of a char array. The data
member len is being used to hold the length of the array.
class example
{
private:
char *str;
int len;
public:
example( ); // one normal constructor
example(char *s); // another normal constructor
example(const example &st) //Deep copy constructor
{
len = st.len;
str = new char [len + 1];
strcpy(str, st.str);
}
// other stuff
};
Page 45
Lab 5 - Shallow Copy/ Deep Copy, Working With Arrays
When working with copy constructors it is important to remember that the copy constructor function prototype is the
same for both shallow copy and deep copy. Hence the difference lies in the fact that dynamic data members are
being handled or not. To determine if a deep copy or shallow copy constructor is being used you have to study the
copy constructor body.
class example
{
private:
float a[10]; public: //array as a data member
example()
{ // normal constructor
Given below is a class named example that contains a dynamic floating point array “a”. This array can be initialized
with a constructor or with a simple member function as follows. Since this code works with a dynamic array
therefore the size of the array can be provided at run time. In this particular code since the size is not passed there
may be a possibility that the programmer crosses the array boundary.
class example
{
private:
float *a; public: //Dynamic array as a data member
example()
{ // normal constructor
a=newfloat[10];
//size can be passed from main to constru
Given below is a class named example that contains a dynamic floating point array “a”. This array can be initialized
with a constructor or with a simple member function as follows. Since this code works with a dynamic array
Page 46
Lab 5 - Shallow Copy/ Deep Copy, Working With Arrays
therefore the size of the array can be provided at run time. In this particular code since the size is not passed there
may be a possibility that the programmer crosses the array boundary.
Another option which is very popular among programmers is that the size of the array can be stored as a data
member.
class example
{
private:
float *a; public: //Dynamic array as a data member
example(int size)
{
a=newfloat[size]; to the constructor
//The size is passed from the main
}
void showall (example arr[ ], int size)
//Size is passed to restrict from crossing array boundary
{
for(int i=0; i<size; i++)
{
for(int j=0; j<size; j++)
{
cout<<arr[i].a[j];
}
}
}
};
int main()
{
const int size=10;
example obj1[size]=example(size);
//array of objects initialized with parameterized constructor
example obj2;
Page 47
Lab 5 - Shallow Copy/ Deep Copy, Working With Arrays
Figure 1: The “english” class demonstrating the use of a constructor and a copy constructor.
Page 48
Lab 5 - Shallow Copy/ Deep Copy, Working With Arrays
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab05
7.3 Outcomes
After completing this lab, students will be able to conveniently use a copy constructor in both deep copy and
shallow copy mode. Further the students will have the ability to comfortably use arrays in their various forms both
inside and outside the class.
7.4 Testing
Test Cases for Practice Task-1
Sample Inputs Sample Outputs
Colour = Hot Red After selective copying only the permanent attributes contain
Owner = Ali Raza values.
Year of manufacture = 2013 Colour = Hot Red
Seats = 2 Owner =
Cubic Capacity = 5700 Year of manufacture =
Engine number = 123456 Seats = 2
Frame number = 987654 Cubic Capacity = 5700
Engine number =
Frame number =
Page 52
Lab Manual for Object Oriented Programming
(LAB-06)
Friend Functions and Friend Classes
Page 53
Lab 6 - Friend Functions and Friend Classes
1. Introduction
In object oriented programming one of the basic goals was to enforce encapsulation and data hiding. This is a
feature that ensures that class members are not accessible openly. We want to provide access to class members
through a regulated mechanism in which all accesses are accountable and legal.
Friend functions and friend classes provide a technique through which you can relax the access specifiers and
provide direct access. Although this seems an attractive technique but it is not liked by hardcore programmers
because of its over relaxing attitude. The concept of friend functions is still important because they need to be used
in operator overloading which will be practiced in the next lab. Hence this lab attempts to build new concepts which
will be used in the next lab.
3. Concept Map
Before going to the syntax of friend functions it is important that we highlight why they are needed. Friend functions
provide a relaxing mechanism through which we can access the private data members of a class directly without any
question being asked. This does not mean that we have relaxed the access specifiers. A friend function provides
access to the private and public data members of a class from only within its body. Friend functions are needed
because sometimes if we have multiple classes and we want to manipulate the class members through a single
function.
Page 54
Lab 6 - Friend Functions and Friend Classes
Another similar scenario is when we want a regular function (that is not member of a class) to access private
members of a class. The final scenario is the use of friend functions in operator overloading (will be discussed in lab
7).
Always remember that friend functions are not members of a class they are just regular functions with special
privileges. In order to make a friend function you have to specify that a particular function is a friend function. This
can be achieved through the following syntax:
class second
{
private:
int mem1; int mem2;
public:
friend void fun( first, second );
}; //Friend function prototype
void fun( first o1, second o2) //Note that friend is not written
{
cout<<o1.member1<<o1.membern; cout<<o2.mem1<<o2.mem2;
}
void main( )
{
first obj1; second obj2;
In the syntax above it must be understood that access specifiers are not applicable on friend functions i.e. whether
you write the function in public or private it has no effect. Another important thing to always remember is that it is
compulsory to write the keyword friend with the function prototype but writing the friend keyword in the function
definition will result in a syntax error. In the above code the friend function is bridge between two classes using a
single function. Creating this environment is purely the programmers choice. It is not necessary that you have a
function working like a bridge. You can always have a single friend function inside a single class.
When discussing friend functions one must remember that friend functions are never part of a class. They are written
in the class to show that they have a friendship with the class. Friend functions are not called using the dot notation
or by using the scope resolution. Friend functions are called like a conventional function. Now when using the friend
function we can access both public and private data members directly as if there is no such thing as an access
specifier.
Page 55
Lab 6 - Friend Functions and Friend Classes
An important note regarding friend functions is that these functions should not be used to relax the access specifiers.
Secondly the friendship of a function is one sided i.e. the function can access the class members but the class cannot
access deceleration that are made inside the function.
class second
{
private:
int mem1; int mem2;
public:
void fun( first o1)
{ //Friend function prototype
cout<<o1.member1<<o1.membern; cout<<mem1<<mem2;
}
};
void main( )
{
first obj1; second obj2;
obj2.fun( obj1);//cannot call using obj1! Obj1 does not contain a function called fun
}
Page 56
Lab 6 - Friend Functions and Friend Classes
Find the sum of 𝑎1 + 𝑎2 + 𝑎3 + ⋯ + 𝑎𝑛 arithmetic series. In an arithmetic series the difference between two
6.3 Walkthrough Task CLO(2,4)
consecutive numbers is the same throughout the series. Your class is composed of four data members i.e. the first
𝑛
n terms which has the formula 𝑆 = 𝑎 + 𝑎 . Use a friend function to compute the sum of the series.
entry of the series, last entry of the series, total number of entries for which sum is required and finally the sum up to
𝑛 2 1 𝑛
class series
{
friend class sum; int first; //Friend class declaration
int nterm; int entries; int sumn;
//First number
//Last number
//Total number of entries
//Sum up till n terms
public:
series(int f, int n, int e)
{
first=f; nterm=n; entries=e;
}
friend void display(series);
};
//Simple friend function
class sum
{
public:
void series_sum(series &obj)
{
obj.sumn=(obj.entries)*(obj.first+obj.nterm)/2;
}
};
Page 57
Lab 6 - Friend Functions and Friend Classes
int main()
{
series obj1(6,96,31); sum obj2; obj2.series_sum(obj1);
//(first term, last term, totaldisplay(obj1);
number of terms)
system ("pause"); return 0;
}
//Call the friend function
Figure 1: The series class and the sum friend class. The display function is a friend function.
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab06
The quadratic equation is 𝑎𝑥2 + 𝑏𝑥 + 𝑐 = 0 and its roots can be determined using the quadratic formula as
possible methods of solving the quadratic equation, a very popular method is through the use of quadratic formula.
−𝑏 ± 2 − 4𝑎𝑐
follows:
Page 58
Lab 6 - Friend Functions and Friend Classes
2𝑎 where 𝑎 ≠ 0
Page 59
Lab 6 - Friend Functions and Friend Classes
Your task is to create a class named equation which will have the data members a, b and c which are the
coefficients of the quadratic equation. The class will have two more data members namely proot and nroot which
stand for the positive root and negative root of the equation. Suppose that variables a, b and c are integers. Where
proot and nroot are floats.
Construct the class objects by using a nullary constructor.
Then design a friend function which will determine the proot and nroot of the equation.
Create another friend function which will display the values of proot and nroot.
7.4 Outcomes
After completing this lab, students will be able explain the difference between a member function and a friend
function. The students will be able to create friend functions and friend classes. Further they will be comfortable
with the manipulation of objects using both friend functions and classes.
7.5 Testing
Test Cases for Practice Task-1
Sample Inputs Sample Outputs
a =1; proot= 1
b =2; nroot = -3
c =-3
𝑎 + 𝑏 + 𝑐 2 =36
Sample Inputs Sample Outputs
𝑎 − 𝑏 − 𝑐 2 = 16
a=1
b=2
c=3 Mean = 2
Page 60
Test Cases for Practice Task-3
Sample Inputs Sample Outputs
Create the following entries for 3x3 arrays Results should be as follows.
𝐴= 4 5 6
1 2 3
𝐴 + 𝐵 = 8 10 12
2 4 6
7 8 9
14 16 18
𝐵= 4 5 6
1 2 3
7 8 9
1. Introduction
In object Oriented Programming perhaps the most exciting and interesting feature is the adaptation of operators
Page 61
according to our class. We are all familiar with the use of different operators with primitive data types. But when it
comes to abstract data types we have to define each operator individually. The greatest advantage of defining each
operator is that we can adapt/ modify an operator according to our class and the objects.
As the name indicates, operator overloading is a basically an operator function whose functionality has been
overloaded. In this lab we will explore the concept of operator adaptation and their overloading. Later on we will
overload some operators for problems related to real world. This lab will explain how friend functions for
overloading stream operators.
3. Concept Map
Operator overloading is an attractive feature offered to programmers using classes and objects. It allows you to
create class objects and then manipulate them using operators just like variables of primitive data types. For
example we can add two integers by using the plus operator, but what happens when we apply the plus operator to a
class object. Without the help of operator overloading we cannot manipulate class objects using mathematical and
logical operators.
Page 62
Lab 7 – Introduction to Operator Overloading
Some people have the opinion that operator overloading only makes your class complex and less understandable.
Another opinion which people have is that we do not need operator overloading because we can use typical member
functions to achieve a similar solution. Both of these opinions are greatly flawed, first of all operator overloading
does not increase the complexity of your code because it provides increased understandability and clarity to the
programmer. The second and most important fact is that you could always use regular member functions to create a
similar mechanism but C++ provides you with a proper technique for incorporating operators in your code. Operator
overloading has an added benefit that it allows the user to manipulate objects using proper operator symbols. This
feature cannot be achieved using member functions.
class DoB
{
private:
int month, day, year;
public:
DoB( )
{
cout <<“Nullary constructor";
month = day = year = 0;
}
~DoB ( )
{
cout << ”Destructor called";
}
friend ostream & operator << ( ostream & os, DoB &d );
friend istream & operator >> ( istream & is, DoB &d );
};
Page 64
Lab 7 – Introduction to Operator Overloading
Page 65
Lab 7 – Introduction to Operator Overloading
Page 66
Lab 7 – Introduction to Operator Overloading
Figure 1: The “toll” class demonstrating the use of various overloaded operators
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
Page 67
Lab 7 – Introduction to Operator Overloading
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab07
Your task is to overload the prefix and postfix increment operators for a class called roundoff. The roundoff class
has a floating point data member called number. Overload the operators as follows.
Overload the stream insertion and extraction operators to input/ output the data.
Prefix increment – When this operator is called there will be an increment in the integer part of the number. For
example if our original number is 3.5 then after prefix increment the result will be 4.5
Postfix increment - When this operator is called there will be an increment in the fractional part of the number.
For example if our original number is 3.5 then after postfix increment the result will be 3.6.
7.4 Outcomes
After completing this lab, students will be able to customize an operator so that it works with their classes. Students
will be able to redefine familiar mathematical operators and also the stream insertion and extraction operators.
7.5 Testing
Test Cases for Practice Task-1
Sample Inputs Sample Outputs
obj1= 10 The average distance covered is 23.33
obj2= 20
obj3= 40
obj4= 20
obj5= 30
obj6= 20
Provide any value for fuel
Obj1+obj2+obj3+obj4+obj5+obj6/6
Page 69
Lab Manual for Object-Oriented Programming
(LAB-08)
Inheritance in Object Oriented Programming
Page 72
Lab 8 - Inheritance in Object Oriented Programming
Page 73
Lab 8 - Inheritance in Object Oriented Programming
CLO(1,2,4)
Lab 08: Inheritance in Object Oriented Programming
1. Introduction
Object-Oriented Programming (OOP) strongly supports reusability and in this regard inheritance is perhaps the
strongest way of reusing the features of a class i.e. attributes (data member) and behaviors (functions). Following the
OOP paradigm, C++ allows the inheritance among classes so that the characteristic(s) of one class is/are inherited by
the other class(es). Hence, you can say that the derived classes receive some their attributes from which the derived
class is inherited. A major advantage of inheritance is that it allows the reusability of code. Hence, the programmer
can simply create new (child) class(es) by using other (parent) class(es).
While considering the advantages of commonality between classes, in C++, you are able to manage your classes in a
way that a class (child/sub class) can extend the functionality by inheriting the attributes and behaviors of an
existing class commonly known as base/super class. In simple words, you can define a class with certain data fields
and/or member functions and then identify other class(es) that can share these data fields and functions. In typical
C++ inheritance, a class or classes known as derived class(es), subclass(es) or child class(es) is/are able to inherit
certain attributes and behavior of pre-existing class(es) that are known as base class(es), superclass(es), or parent
class(es). In practice, base classes are more general while derived classes are specialized version of base classes and
due to this reason, it is said that inheritance maintains generalization and specialization. With inheritance, you can
greatly save the time and lessen the effort to write duplicate code.
Concerning inheritance syntax in C++, if you have a base class named person inherited by a derived class named
student then you have to write code in the following way
class Person
{
//code statements go here
};
class Student: public Person
{
//code statements go here
};
In case of derived class’s object instantiation, default/no-argument constructor for the base class(es) are
automatically called first and are followed by calling derived class’s constructors. If base class(es) is/are without
default/no-argument constructor, then it is must to call explicitly any base class’s constructor even if there is no need
to call a constructor.
Page 74
Lab 8 - Inheritance in Object Oriented Programming
3. Concept Map
Inheritance is one of the most important building blocks of OOP. The concept of reusable classes is helpful to
manage objects. You can create new classes (derived classes) that are able to inherit certain attributes and behavior
of their ancestor or base class(es). Prior to working with inheritance, it is important to consider the following aspects
of inheritance.
Inheritance represents “is-a” relationship in OOP i.e. any specific object is a type of a more general class
of object. For example, Train is a type of Vehicle
By design, a derived class should inherit all attributes and behaviors of its base class(es)
While declaring its own data fields a derived class can extend the features of its base class(es)
While defining new functionality, a derived class can modify the behavior provided by the base class(es)
Inheritance in OOP saves a lot of work and time. You can save additional work as some of the object
definitions(class) already exists. Time saving is due to the reason that much of the code has already been written and
tested.
Design a class named Person and its two derived classes named Student and Teacher.
Draw UML diagram for each class and show inheritance relationship among all classes.
Page 75
Lab 8 - Inheritance in Object Oriented Programming
In the main() function make three objects of class Trigon while considering the shapeName as “threeangle” for
each object. In addition, it is required to invoke all the functions of Trigon class.
5.2.2 Task-2
Try to create a clasas of bank account: CLO(2,4)
The BankAccount class has the following attributes i.e.
accountNumber, accountHolderName, and balance
A parameterized constructor to initialize data fields with user-defined values
Create two derived classes i.e. CheckingAccount and SavingsAccount. Both these classes have
A three argument constructor to initialize base class’s data fields
Two functions i.e. deposit(amount) to deposit certain amount and witdraw(amount) to withdraw certain
amount
The withdraw function of CheckingAccount class has an overdraft limit but SavingsAccount cannot be overdraft.
In the main() function, create an object of both SavingAccount and CheckingAccount class. Moreover, test the
functionality of their respective deposit(amount) and withdraw(amount) functions while passing different amounts
as parameter.
6.1 Tools
Visual Studio 2008.
In the source file, which is created in the project “Inheritance” write following C++ code:
Page 76
Lab 8 - Inheritance in Object Oriented Programming
.
Figure 1: Base and Derived Classes
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
Page 77
Lab 8 - Inheritance in Object Oriented Programming
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab08
Implement all class definitions with their respective constructors to initialize all data members and functions to
compute the total income of an employee. In the main() function, create an instance of both classes (i.e.
HourlyEmployee and PermanentEmployee) and test the working of functions that calculate total income of an
employee.
Derive two classes from the BankAccount class i.e. CurrentAccount and the SavingsAccount. Both classes
(CurrentAccount and SavingsAccount) inherit all attributes/behaviors from the BankAccount class. In addition,
followings are required to be the part of both classes
Appropriate constructors to initialize data fields of base class
A function named amountWithdrawn(amount) to withdraw certain amount while taken into account the
following conditions
o While withdrawing from current account, the minimum balance should not decrease Rs. 5000
o While withdrawing from savings account, the minimum balance should not decrease Rs. 10,000
amountDeposit(amount) to deposit amount in the account
In the main() function, create instances of derived classes (i.e. CurrentAccount and SavingsAccount) and invoke
their respective functions to test their working.
Page 78
7.3 Outcomes
After completing this lab, student will be able to understand the implementation and design of Inheritance in C++.
7.4 Testing
Page 80
Lab 9 - The Protected Access Specifier and Types of Inheritance
1. Introduction
So far, you have learned the importance and use of two (public and private) access specifiers within class(es) of C+
+. You know that a class’s member functions are able to access class’s data fields having public or private
accessibility for all times. However, externally created object(s) can only access public data members of that class
and private data members are restricted to be accessed outside the class. For example, consider the following class:
class Examp
{
private:
int attribute;
public:
void show()
{
cout<<attribute;
}
};
Any externally created instance (e.g. Obj) of class Examp would not be able to access data member(s) directly while
using the dot (.) operator. Hence, in the main() function, the statement Obj.attribute is not legal but the statement
Obj.show() is legal.
It is sufficient to know about public and private access specifiers/modifiers in the absence of inheritance. However,
in case of inheritance, sometimes it is required to access data member(s) of base class in derived class(es) but not
outside these classes. In this situation, you must make access protected for that data member(s) rather than private or
public. Protected access will ensure access of data members only within inheritance hierarchy.
Another important use of access specifiers is their role in the inheritance process. Considering access specification in
C++, inheritance can be private, protected, or public. Each type of inheritance has specific rules to access base
class’s data member(s), which have been explained below.
Public Inheritance:
Syntax: class Student: public Person { };
If a class is derived from a base class with public specifier, then all public/protected member(s) of base class
become public/protected member(s) of derived class. However, private member(s) of base class are never accessible
from derived class directly.
Protected Inheritance:
Syntax: class Student: protected Person { };
If a class is derived from a base class with protected specifier, then all public/protected member(s) of base class
become protected member(s) of derived class. However, private member(s) of base class are never accessible from
derived class directly.
Private Inheritance:
Syntax: class Student: private Person { };
If a class is derived from a base class with private specifier, then all public/protected member(s) of base class
become private member(s) of derived class.
Page 81
Lab 9 - The Protected Access Specifier and Types of Inheritance
3. Concept Map
Inheritance is one of the most important building blocks of OOP. The concept of reusable classes is helpful to
manage objects. You can create new classes (derived classes) that are able to inherit certain attributes and behavior
of their ancestor or base class(es). Prior to working with inheritance, it was important to consider that data
member(s) should have private access and only through public member functions, you can access data members of a
class. However, with inheritance, it is sometimes required to have an intermediate level of accessibility to class’s
data member(s) that exists only within inheritance class hierarchy but not outside these classes.
C++ provides intermediate level of accessibility through protected access specifier. Data member(s) of a base class
with protected accessibility are only be directly accessible within base class and all of its derived classes but not in
other parts of the program. Nevertheless, you should be careful while making data field(s) protected. Use protected
access only where you think that derived classes will use base class data field(s). The access of protected data
members in the derived classes make them less secure than private data members.
Moreover, access specifiers also play their role in the inheritance process. Considering access specification in C++,
inheritance can be private, protected, or public. The effects of access specifiers in inheritance process on derived
class’s member(s) are different as illustrated in Table 2.
Table 2: Inheritance access specifiers and their effect on derived class members
Page 82
Lab 9 - The Protected Access Specifier and Types of Inheritance
From the Rectangle class, derive a class named Cuboid that contains
a data field named height in addition to length and width,
two functions named setHeight and getHeight() to set and get value of height data field, and
a member function named cuboidArea() to calculate the area of a cuboid (length x width x height)
Draw UML diagram for each class and show inheritance relationship between these classes.
Implement both classes and in the main() function, create an instance of ResearchCourse class. Invoke appropriate
functions to display all attribute values as well as the total fee for this particular instance.
5.2.2 Task-2
Derive a class named SpacePoint to imagine a point in a three-dimensional space and has following additional
features:
A data member Z of type integer to represent the z-coordinate of a point in space
Page 83
Lab 9 - The Protected Access Specifier and Types of Inheritance
Implement both the classes and in the main() create two points with different dimensions and invoke appropriate
function to display the distance between these two points.
Page 84
Lab 9 - The Protected Access Specifier and Types of Inheritance
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab09
In the main() function, create objects of ENoteBook and PaperNoteBook classes and show the advantages of using
protected access specifier.
Page 85
Lab 9 - The Protected Access Specifier and Types of Inheritance
Write a main() function that instantiates objects of FolkMusic class and test the functionality of all its member
functions.
Try to Derive a class named StaffService from the class CafeService that holds the following:
Two data members i.e.
o serviceFee,
o the cabinNumber to which the service has been made
A function named totalCharges that returns total cost of an order (including serviceFee + price of food
item(s) served)
A parameterized constructor, which requires arguments for all of its own data fields as well as for the data
fields of base class
A member function named display() to show all the details of an order including orderID, price, and
totalCharges
In the main() function, instantiate an object of class StaffService object and test the implementation of both classes
through this object.
7.4 Outcomes
After completing this lab, student will be able to understand the implementation and design of inheritance as well as
the use of protected access specifier in inheriting classes.
7.5 Testing
Page 86
Table 3: Practice Tasks Confirmation
Page 89
Lab 10 - Multi-level and Multiple Inheritance
Page 90
Lab 10 - Multi-level and Multiple Inheritance
Single Inheritance: a single child class derived from a single base class
Hierarchical Inheritance: multiple child classes derived from a single base class
Multi-level Inheritance: a single derived class inherited from another derived class
Multiple Inheritance: a single derived class inherited from more than one base classes
Hybrid Inheritance: any legal combination of more than one type of inheritance
In particular, the main focus of this lab is concerned with the understanding of multi-level and multiple inheritance.
Multi-level represents the scenario of inheriting attributes and behavior of a class that is already inheriting attributes
and behaviors from other class(es). The syntax of writing C++ code to implement multi-level class hierarchy is
given as under:
class X
{
// code statements go here
};
class Y: public X
{
//code statements go here
};
class Z: public Y
{
//code statements go here
};
...
Multiple Inheritance represents where a single class inherits attributes and behaviors from more than one class. The
syntax to write C++ code for multiple inheritance is given as under:
class X
{
// code statements go here
};
class Y
{
//code statements go here
};
class Z: public X, public Y
{
//code statements go here
};
3. Concept Map
Inheritance is one of the most important building blocks of OOP. The concept of reusable classes is helpful to
manage objects because occasionally it happens that a class may have some features that it can derive from already
existing class(es). Hence, with inheritance, it is sometimes crucial to build multi-level class hierarchies or to derive
class(es) from multiple existing classes. To grasp the concept and need of multi-level and multiple inheritance,
consider the following class hierarchy
Person
Employee Student
Administration Academic
Dean/HOD
Figure 1: Class Hierarchies showing Multi-level and Multiple Inheritance
A person can be an employee or a student. An employee may have rights of admin officer or of academic officer.
These class hierarchies represent multi-level inheritance. However, a Dean or Head of Department (HOD) may have
rights to modify the status already defined by an admin or academic officer. This type of relationship between
classes is an example of multiple inheritance.
C++ facilitates users while supporting the implementation of both multi-level and multiple inheritance. There is no
limitation on the number of levels in multi-level inheritance and there is no limitation on the number of parent
classes from which a child can be derived. Nevertheless, as a good practice, it is recommended to restrict levels and
number of base classes to two in multi-level and multiple inheritance.
Page 92
Lab 10 - Multi-level and Multiple Inheritance
Draw UML diagram for each class and show inheritance relationship between these classes.
Consider the problem description of section 5.1.1 of this lab that deals with three classes i.e. Staff, Professor, and
VisitingProfessor. Implement all these classes and in the main function, Try to create an object of class
VisitingProfessor and invoke its member function display to show total income of a visiting professor.
Try to Consider four classes named Animal, Mammal, Bird, and Bat.
class Animal that includes the functionality of eating and breathing
class Mammal derived from Animal class and has additional functionality of giving birth but not
hatching
class Bird derived from Animal class and has specific functionality of flying
class Bat derived from both Animal and Bird classes while inheriting the functionality of both these classes
Draw UML diagram for each class and show inheritance relationship between these classes. Moreover, illustrate the
implementation of these classes in C++.
Page 93
Lab 10 - Multi-level and Multiple Inheritance
#include<iostream>
using namespace std;
class Student
{
protected:
int registrationNum,marks1,marks2;
public:
void getMarks()
{
cout<<"Enter the Registration number: ";
cin>>registrationNum;
cout<<"Enter the marks: ";
cin>>marks1;
cin>>marks2;
}
};
class SportActivity
{
protected:
int sportsmarks;
public:
void getSportsMarks()
{
cout<<"\nEnter the marks for sports: ";
cin>>sportsmarks;
}
};
class MarksStatment:public Student,public SportActivity
{
int totalMarks,averageMarks;
public:
void ShowStatement()
{
totalMarks=(marks1+marks2+sportsmarks);
averageMarks=totalMarks/3;
cout<<"\ntRegistrattion Number: "<<registrationNum<<"\nTotal marks: "
<<totalMarks;
cout<<"\nAvergae marks : "<<averageMarks;
}
};
Page 94
Lab 10 - Multi-level and Multiple Inheritance
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab10
Page 95
Class Administration has
o A parameterized constructor to receive five arguments to initialize inherited attributes from class
Employee
(Concerning courseID and courseTitle, only null value is allowed to set for an admin officer)
o Two functions i.e. setJobTitle(employee) and getJobTitle(employee) to set and get job title of an
employee
Only an instance of class DeanHOD should be able to modify values for employeeID, designation of an
employee, ID and name of a particular course.
Implement all these classes and within the main function, create instances of all classes (except class Employee) and
test the described working of all these classes.
7.2 Outcomes
After completing this lab, student will be able to understand the implementation and design of Multi-level and
Multiple Inheritance in C++.
7.3 Testing
For Practice Task 1, while inspecting implementation of classes, lab instructor must ensure that student has
taken hold the concept of multi-level and multiple inheritance. Furthermore, it is required to check the
invocation of all functions with the created instances of all mentioned classes.
Page 98
Lab Manual for Object-Oriented Programming
(LAB-11)
Function Overloading and Function Overriding
CLO (1,2,4)
Lab 11: Function Overloading and Function
Overriding
1. Introduction
Earlier in Lab-09, you have already studied that a sub/derived class is able to access all non-private data members
and member functions of the base/parent class. Moreover, besides inheriting attributes and behaviors from base
class(es), the derived class also contains its own data members and member functions.
Function overloading is the availability of various functions within a class that differ from each other in function
signature i.e. various functions share same name with different parameter types or number of parameters.
Inheritance is not necessarily required to overload functions within a program.
On the other hand, in function overriding, there must exists inheritance relationship between classes (i.e. base and
derived) and functions’ signature are also required to be same in both parent and child class(es). However, derived
class(es) redefine function(s) having signature similar to base class’s function(s).
Following code provides an example where both concepts (function overloading and overriding) have been
elaborated:
class Base
{
protected:
void myFunc()
{
cout<<"Base Class’ Function";
}
};
Page 99
In the given example (above),
At first, the class Derived shows function overloading while containing two functions differ from each
other in function signature (i.e. functions myFunc() and myFunc(int))
Secondly, it also shows function overriding as it holds two function implementations with same signature
(i.e. besides myFunc() of its own, it also contains myFunc() inherited from the Base class.
3. Concept Map
Function overloading and function overriding are the two key concepts of a number of modern computer
programming languages.
Overloaded functions provide specific functionalities while taking into account the type/number of parameter(s) they
receive and the fundamental advantage is the cleanliness of code. For example, in the absence of overloading, a
computer program may have several functions with different names to calculate the area of a geometric shape as
shown below:
class GeometricShape{
public:
int squareArea(int sideLength);
int reactangleArea(int length, int width);
int triangleArea(int side1, int side2, int side3);
};
class GeometricShape{
public:
int area(int sideLength);
int area(int length, int width);
int area(int side1, int side2, int side3);
};
On the other hand, function overriding is the ability of redefining a specific behavior (function) of a base class
within derived class(es). Besides the provisioning of a specific modified implementation of a base class function,
function overriding is used to perform runtime polymorphism.
Page
100
Lab 11 - Function Overloading and Function Overriding
Derive a class named Car inherited from Automobile class and contains
An additional data member named color
A parameterized constructor to initialize its own data fields along with the inherited data field
Two functions named setColor and getColor to set and get the color of a Car object, respectively
Derive a class named Limousine inherited from class Car and has its own functions (i.e. setCurrentSpeed,
getCurrentSpeed, setColor and getColor) to set/get speed and color for each of its specific instance
Draw UML diagram for each class and show inheritance relationship between these classes.
Practice a class named Calculator with typical four specific functionalities i.e. addition, subtraction,
multiplication, and division. Implement these functionalities as four functions with two parameters. It is also
required to overload all these functions for int and double data types. In the main function, create an object of class
Calculator and invoke its member functions while passing parameters of int and double type.
Try to Consider a class named Animal having typical function named eat that accepts a parameter of type string.
Three classes i.e. Herbivore, Carnivore, and Omnivore have been inherited from Animal class. All these classes i.e.
Herbivore, Carnivore, and Omnivore must have their own (overridden) eat function.
a) Draw UML diagram for each class and show inheritance relationship between these classes.
b) Implement all these classes
c) In the main function, create instances of Herbivore, Carnivore, and Omnivore classes and invoke eat
function with appropriate string parameter to display the liking of that animal in eating.
In this task, you are required to write a C++ code which would elaborate function overloading. The following lines
show the output of a basic function overloading concept:
In the source file, which is created in the project “FunctionOverloading” write following C++ code:
Page 101
Lab 11 - Function Overloading and Function Overriding
Page 102
Lab 11 - Function Overloading and Function Overriding
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab11
From the Rectangle class, derive a class named Cuboid that contains
a data field named height in addition to length and width,
two functions named setHeight and getHeight() to set and get value of height data field, and
an overriding function named computeArea() to calculate the area of a cuboid (length x width x height)
overriding function named show() to display the details associated with an instance of class Cuboid
Implement these classes and in the main() create instances of each class and test the functionality of overridden
member functions with these instances.
Page 103
Lab 11 - Function Overloading and Function Overriding
o A parameterized constructor to initialize data members that they inherit from the class
MusicalInstrsument
In the main(), create instances of MusicalInstrument, Flute and Guitar classes. Invoke displayPrice() with
MusicalInstrument object while passing references of Flute and Guitar instances.
7.3 Outcomes
After completing this lab, student will be able to understand the difference between function overloading and
function overriding within a class or class hierarchies.
7.4 Testing
For Practice Task 1, lab instructor must confirm the implementation of classes i.e. GeometricShape,
Rectangle, and Cuboid. With instances of each class, test the invocation of proper overridden function.
For Practice Task 2, lab instructor ensures the invocation of displayPrice() function with the
MusicalInstrument instance while receiving references of the instances of Flute and Guitar classes.
Page 104
Lab 11 - Function Overloading and Function Overriding
Page 105
Lab 12 - Polymorphism in Object Oriented Programming
Page 107
Lab 12 - Polymorphism in Object Oriented Programming
A member function of a base class can be made a virtual function if it is probable to redefine (override) this function
in the derived class. The significance of making a function virtual becomes evident when you want to invoke
function of derived class from a pointer of base class referencing derived class‟s object. Following code provides an
example of polymorphism mechanism in C++.
class Base
{
public:
virtual void func()
{
cout<<”Base Class Function”;
}
};
Upon calling func() with bPtr, Derived class func() will be invoked and output would be “Derived Class
Function”. In the absence of virtual keyword, func() of base would be called each time. Hence, it can be concluded
that virtual keyword allow a pointer of base class to call appropriate function of any of its derived class to whom it
is referencing. In this way, each time a different function will be invoked with the same function call. With
polymorphism, compiler does not know which function to call at compile and thus appropriate function call is
deferred to runtime. At runtime, the type of object that a base class pointer is pointing is recognized to call proper
function. This is known as dynamic or late binding.
Virtual keyword can also be used with destructors and classes. However, virtual keyword possesses different
meanings when used with destructor and classes as explained below.
Page 108
Lab 12 - Polymorphism in Object Oriented Programming
Virtual Destructors:
In practice, it is always recommended to make the base class destructor as virtual. In the absence of virtual keyword
with base class destructor, upon deletion of any derived class‟s object only destructor of base class would be called.
class Base
{
protected:
void func()
{ cout<<”A Base Class Function”; }
};
class Derived1: public Base{ };
class Derived2: public Base{ };
class Derived3: public Derived1, public Derived2
{ };
In the code above, both (Derived1 and Derived2) classes contain a copy of func(), which is inherited from class
Base. Upon the invocation of func() with an object of Derived3 class, compiler would be unable to decide which
copy to use.
To overcome this situation, it is required to use virtual keyword with base class inheritance. Hence, the above code
would be implemented as
class Base
{
protected:
void func()
{ cout<<”A Base Class Function”; }
};
class Derived1: virtual public Base{ };
class Derived2: virtual public Base{ };
class Derived3: public Derived1, public Derived2
{ };
class Base
{
protected:
virtual void func() = 0;
};
Instantiation of an abstract class is not possible and you should override pure virtual function in derived class(es).
3. Concept Map
Following encapsulation and inheritance, polymorphism is the third important capability of OOP paradigm. The
fundamental inspiration behind polymorphism is that of dynamic binding. In this way, at compile time, compiler
knows nothing about which function to call. On the contrary, decision is made at runtime. Polymorphism helps
programmer to make program in general rather than specific. In simple words, it provides a single interface with
different implementations. Moreover, polymorphism facilitates program extensibility while permitting new derived
classes and functions to be added to an inheritance hierarchy without modifying application programs that already
utilize various interfaces of that inheritance hierarchy. However, for beginners, it is difficult to grasp and implement
the concept of polymorphism, dynamic binding, and abstract classes.
Derive a class named CourseRecord inherited from Record class and contains
Two additional data members i.e. marksCourse1 and marksCourse2
A parameterized constructor to initialize its own data fields along with the inherited data fields
Two getter functions that return the value of marksCourse1 and marksCourse2, respectively
Derive a class named CourseResult inherited from class CourseRecord and has
A data field named totalMarks
A function named marksObtained that returns totalMarks (i.e. marksCourse1 + marksCourse2) of a
student
A member function named display to show rollNo, course1Name, course2Name, marksCourse1,
marksCourse2, and totalMarks
Draw UML diagram for each class and show inheritance relationship between these classes.
Page 110
Lab 12 - Polymorphism in Object Oriented Programming
Try to Consider four classes i.e. Person, Staff, Professor, and Researcher with the following inheritance
hierarchy: Class Researcher is derived from both Staff and Professor classes that are ultimately derived from
class Person. Class Person has two attributes i.e. name and age and one member function display() to show its
attribute values. Class Staff has two attributes i.e. staffID and department.
Class Professor has two attributes i.e. courseID and courseName for the course he/she is teaching.
Class Researcher has additional attributes named labID and experimentNo for laboratory and experiment under his
supervision.
Draw UML diagram for each class and show inheritance relationship between these classes.
Illustrate the implementation of classes that have been specified in Task-1 using C++ compiler in a way that avoid
diamond problem of multiple inheritance.
6.1 Tools
In this task, you are required to write a C++ code which would elaborate polymorphism concept. The following lines
show the output of a basic polymorphism concept:
In the source file, which is created in the project “Polymorphism” write following C++ code:
Page 111
Lab 12 - Polymorphism in Object Oriented Programming
Figure 1: Polymorphism
Page 112
Lab 12 - Polymorphism in Object Oriented Programming
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab12
A class named Desktop inherits Computer class and adds fields representing
color, monitor size, and processor type and
Override function named show() to display values of its all attributes
A class named Laptop inherits Computer class and adds fields representing
color, size, weight, and processor type and
Override function named show() to display values of its all attributes
Write a main() function that instantiates objects of derived classes to access respective show() function using
dynamic binding.
Page 113
In the main function, create instances of derived classes to access respective print() function using dynamic
binding.
7.3 Outcomes
After completing this lab, student will be able to implement the concepts of virtual functions, dynamic binding, pure
virtual function, and abstract classes.
7.4 Testing
For Practice Task 1, it is required to check the assignment of derived class instances to base class
pointer. Moreover, (while considering the dynamic binding) test the invocation of respective show()
function.
For Practice Task 2, it is required to check the assignment of derived class instances to base class
pointer. Moreover, (while considering the dynamic binding) test the invocation of respective print()
function.
Page 123
1. Introduction
In general, a template is used to represent a pattern. In programming, occasionally, a group of functions and/or
classes differ from each other simply in terms of parameter types or types of data members, respectively. In these
situations, templates are used to avoid redundant coding and can be practiced in two ways i.e. with functions and
with classes. In C++, templates facilitate the programmer to define a generic function or class that is able to perform
the same task with variables of different data types (including objects of different classes). The syntax of writing a
generic function in C++ is given as under:
}
You can call this function in different ways i.e. with parameters of types int, long, float, double as:
TemplateExample<int> TE1;
TemplateExample<double> TE2;
It is clear from above examples that prior to coding a function template or class template you have to provide
template definition statement starting with the keyword template. This template reserved word in C++ informs the
compiler that programmer is going to define a function or class template. Further, the variable with reserved word
class or typename within angle brackets (< >) is known as the template argument. This template argument is
replaced with specific data type with each function call statement.
3. Concept Map
To deal with overloaded functions and various classes (that differ from each other in terms of the types of data
fields), C++ assists programmer to define generic functions and classes while using the concept of templates. It is
important to mention here that templates do not save the amount of memory to be used by different functions or
class objects. However, template approach (that is a very special kind of code reusability) saves the time of writing
multiple functions and classes with same logical task. In this way, later on, modification(s) can be performed easily
while changing code at one place instead of multiple places.
The statement of template definition in C++ code by itself is not able to generate any code. Code generation for a
specific template function takes place at the time of function invocation. This is due to the fact that upon function
invocation compiler comes to know about the type to substitute template parameter. This is known as instantiating
the function template.
Concerning class templates in C++, it is important to point out here that C++ provides a powerful and versatile
collection of functions and classes for common data structures i.e. vector, stack, queue etc. This collection of classes
is known as Standard Template Library (STL). Functions and classes in STL provides well-organized and extensible
framework to develop certain applications.
4. Homework before Lab
A function named exchange that takes two values as its parameters and is responsible to swap these values. It is
required from you to implement exchange function as a template. In the main function, test the working of
exchange function by invoking it with parameters of int, long, double, and char data type.
Make the class Calculator into a template and in this way, a user would be able to instantiate it using different data
types for the data members. In the main function, instantiate two objects of Calculator class with data members of
type integer and float, respectively and invoke all functions of class Calculator.
Page 118
Lab 14 - Function and Class Templates
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab14
A single data member as an array named stack of size 50 to store certain elements
A constructor to initialize stack with value 0 or 0.0 at all its indexes
Three member functions i.e. push(type) to add elements in the Stack, pop() to remove elements from the
stack, and currentStatus() to check whether the array is filled or not. (A filled array is an array that has
non-zero value at all of its indexes).
In the main() function, create three objects with different data types of class GeneralStack and test the functionality
of member functions for various values of data members for these objects.
Page 119
Lab 14 - Function and Class Templates
7.4 Outcomes
After completing this lab, student will be able to understand the use and working of function and class templates in
C++.
7.5 Testing
Test cases for Practice Lab 1
For Practice Lab 3, lab instructor should check the creation of three instances of GeneralStack class while
each having an array of different data type. Moreover, check the required functionality of member
functions with these instances.
Page 130
Lab 14 - Function and Class Templates
Page 130
Lab Manual for Object-Oriented Programming
(LAB-15)
Exception Handling
Page 131
Lab 15 - Exception Handling
1. Introduction
Lab 15: Exception Handling CLO(1,2,4)
Page 132
Lab 15 - Exception Handling
Exceptions are runtime errors in a programming language that change the regular flow of program execution. A
typical example of exception is division by zero during a program execution; however, there are a number of
situations that can cause exceptions i.e. array index out-of-bounds, file opening fail, and running out of memory.
The response to the occurrence of an exception (or runtime error) is known as exception handling. Different
languages provide specific functions called exception handlers to deal with exceptions. These specific functions are
a kind of built-in code to handle the known exceptions.
C++ provides try-catch block to handle exceptions. You have to place the exception suspected code in the try block.
In the absence of exception occurrence, programs continue to follow the normal flow of execution. However, upon
the generation of exceptions within try block, control is transferred to the exception handling block i.e. known as
catch block. It is must to place the catch block immediately after the try block. The syntax of the exception handling
in C++ is given as under:
try
{
// code statements here
}
catch (type e)
{
//code to handle the exception(s)
}
Usually, statements in the try block run without throwing any kind of exception, however, infrequently various types
of exceptions can occur. A single catch block is able to handle only a specific type of exception. Therefore, in order
to handle any kind of expected runtime error, C++ permits to use multiple catch blocks with a single try block. The
syntax to use multiple catch blocks with a single try block is given as under:
try {
// code statements here
}
catch (int param) { // code to handle int type of exception }
catch (char param) { // code to handle char type of exception }
catch (...) { // code to handle any kind of exception }
3. Concept Map
To deal with anomalous or exceptional situation in the running code, programming languages facilitate programmers
with the provisioning of exception handling mechanism. At present, C++ provides try-catch block to handle
exception. However, to handle exceptions, older C++ programs use the logic with decision statements (i.e. if-else or
switch statements). As an example, pseudocode to exception handling in older C++ is given as under:
Execute statement(s)
If error occurs, do some error processing
Else execute next statements
If error occurs, do some error processing
Else execute next statements
Page 133
Lab 15 - Exception Handling
...
Due to a number of reasons, this type of approach has various shortcomings as explained under:
error detection/handling logic is intermingled with the program logic
it is difficult to read the program
due to constant decision testing for rare exceptional circumstances, program execution becomes
less efficient
Although, exception handling mechanism using try-catch block is an advantage over if-else construct but it is not a
recommended practice to use try-catch block for simple errors that are already expected within a program. These
types of errors should be handled locally. Hence, you should not overuse catch block because usually exceptions are
permitted to propagate up the call stack. It is also important to consider the order of exceptions that are defined in
catch blocks. It is essential to use a catch block with a derived class type before the catch block with base class type.
Create another class named RegException that should hold a member function named exceptionCause with an error
message. In Registration class, it is required to throw an exception of type RegException if user enters invalid
registration number (string with more than five characters) or registration fee (if given in characters). Upon
catching exception, invoke function of RegException class to display the error message.
Draw class diagrams of both classes and show interaction between these classes.
Page 134
Lab 15 - Exception Handling
Try to Create a class named Fan. It contains two data fields i.e.
A member function named getValues is required to get values for both data fields. If the entered price would be less
than Rs. 2000 or greater than Rs. 8000, then entered price will be thrown as an exception. Exception must be caught
within the getValues function to show some appropriate message. In the main() function, create three objects of
Fan class and test the code for entries of all three objects.
A char type data member named hLocation to store value i.e. „S‟, „N‟, „W‟, or „E‟
A float type data member named housePrice that stores the price of the house
An int type data member named roomCount representing the number of total rooms within a specific house
A parameterized constructor that takes values for all data members
Three functions named setHLocation, setHousePrice, and setRoomCount to modify the values for house
location, house price, and number of rooms
A show() function to display the current values of the data members associated with a particular object
The main() function must catch all exceptions (i.e. invalid house location if it is any character other than S, N, W, or
E, invalid house price if it is less than Rs. 100,000, and invalid roomCount for any value less than equal to zero)
generated from setter functions (i.e. setHouseNo, setHousePrice, setRoomCount).
Tools
Visual Studio 2008.
In the source file, which is created in the project “ExceptionHandling” write following C++ code:
Page 135
Lab 15 - Exception Handling
6.3.2 Compilation
After writing the code, compile your code according to the guidelines mentioned. Remove any errors and warnings
that are present in your code.
Page 136
Lab 15 - Exception Handling
6. Practice Tasks
This section will provide more practice exercises which you need to finish during the lab. You need to finish the
tasks in the required time. When you finish them, put these tasks in the following folder:
\\dataserver\assignments$\OOP\Lab15
In the main() function, create three objects of type LCD and test the class implementation for various values of data
members for these objects. Exceptions of inner class types would be thrown and caught in main() while following
the criteria that if model number is not started with character „V‟, if screen size entered is not between 30 and 55, or if
the price entered is a negative number or a value greater than Rs. 90,000.
7.4 Outcomes
After completing this lab, student will be able to throw and handle exceptions (using try-catch block) in a C++
program.
Page 137
7.5 Testing
Lab instructor must consider the following:
For Practice Task 1, test the exception generation of inner class type and its handling in the main()
function.
For Practice Task 2, test that exceptions generated/thrown in insert and delete functions must be handled
within the main().
For Practice Task 3, test the working of exception handling mechanism with single try block having
multiple associated catch blocks to handle a relevant thrown exception message.