C++ Notes
C++ Notes
C++ Notes
Evaluation:
Theory Practical Total
Sessional 30 20 50
Final 50 - 50
Total 80 20 100
Course Objectives:
• To familiarize with Object Oriented Concept.
• To introduce the fundamentals of C++
• To enable the students to solve the problems in Object Oriented technique
• To cope with features of Object Oriented Programming
Course Contents:
Chapter Content Hrs.
5 Polymorphism 8
Polymorphism in programming language, Varieties of polymorphism, compile time
polymorphism, function overloading, operator overloading, type conversion, polymorphic
variable, run time polymorphism, object pointer, this pointer, virtual function, overriding,
deferred method, pure polymorphism.
Laboratory Work
There shall be 20 exercises in minimum, as decided by the faculty. The exercises shall encompass a broad
spectrum of real-life and scientific problems, development of small program to the development of fairly complex
subroutines, programs for engineering applications and problem solving situations. Laboratory assignments will
be offered in groups of two to four for evaluation purpose. In general, the Laboratory Work must cover
assignments and exercises from the following areas:
Textbooks:
1. Budd, T., An Introduction to Object Oriented Programming, Second Edition, Addison-Wesley, Pearson
Education Asia, ISBN: 81-7808-228-4.
2. R. Lafore, Object Oriented Programming in Turbo C++, Galgotia Publications Ltd. India, 1999
Reference Books:
In a multi-function program, many important data items are placed as globally. So that
they may be accessed by all the functions. Each function may have its own local data. The
figure shown below shows the relationship of data and function in a procedure-oriented
program.
Procedural languages are difficult to relate with the real world objects.
Procedural codes are very difficult to maintain, if the code grows larger.
Procedural languages does not have automatic memory management .Hence, it makes
the programmer to concern more about the memory management of the program.
The data, which is used in procedural languages are exposed to the whole program. So,
there is no security for the data.
Creation of new data type is difficult. Different data types like complex numbers and
two dimensional co-ordinates cannot be easily represented by POP.
The data of an object can be accessed only by the function associated with that object.
The fundamental idea behind object-oriented programming is to combine or
encapsulate both data (or instance variables) and functions (or methods) that operate
on that data into a single unit. This unit is called an object. The data is hidden, so it is
safe from accidental alteration. An object’s functions typically provide the only way
to access its data. In order to access the data in an object, we should know exactly
what functions interact with it. No other functions can access the data. Hence OOP
focuses on data portion rather than the process of solving the problem.
It is easy to model a real system as programming objects in OOP represents real objects.
The objects are processed by their member data and functions. It is easy to analyze the
user requirements.
Elimination of redundant code due to inheritance, that is, we can use the same
code in a base class by deriving a new class from it.
Modularize the programs. Modular programs are easy to develop and can be
distributed independently among different programmers.
In OOP, data can be made private to a class such that only member functions of the
class can access the data. This principle of data hiding helps the programmer to build a
secure program that cannot be invaded by code in other part of the program.
With the help of polymorphism, the same function or same operator can be used for
different purposes. This helps to manage software complexity easily.
Large problems can be reduced to smaller and more manageable problems. It is easy to
partition the work in a project based on objects.
Program complexity is low due to distinction of individual objects and their
related data and functions.
Disadvantages of Object Oriented Programming
1. Large Programs are divided into 1. Program are divided into entity called
smaller self- contained program objects.
segment known as functions.
2. Focuses on process/logical structure 2. Object oriented Programming is
and then data required for that designed which focuses on data.
process.
3. Structured Programming follows top- 3. Object oriented Programming follows
down approach. bottom-up approach.
4. Data and functions don’t tie with each 4. Data and functions are tied together.
other.
5. Structured programming is less secure 5. Object oriented programming is more
as there is no way of data hiding. secure as having data hiding feature.
There is a designated receiver for that message (the receiver is some object to which
the message is sent).
Interpretation of the message is dependent on the receiver and can vary with
different receivers.
There is a late binding between the message (function or procedure name) and the
code fragment (method ) used to respond the message.
In a procedure call
Alan Kay, considered by some be the father of object-oriented programming, identified the
following characteristics as fundamental to OOP.
1. Everything is an object.
2. Computation is performed by objects communicating with each other, requesting that
other objects perform actions. Objects communicate by sending and receiving
messages. A message is a request for action bundled with whatever arguments may be
necessary to complete the task.
3. Each object has its own memory, which consists of other objects.
4. Every object is an instance of a class. A class simply represents a grouping of similar
objects, such as integers or lists.
5. The class is the repository for behavior associated with an object. That is, all objects that
are instances of the same class can perform the same actions.
6. Classes are organized into a singly rooted tree structure, called the inheritance
hierarchy. Memory and behavior associated with instances of a class are automatically
available to any class associated with a descendant in this tree structure.
Alternatively, Abstraction is a mechanism to displaying only essential information and hiding the
details.
Making use of abstraction
a)Procedure and function:
Procedure and function are main two first abstraction mechanism to be widely used in
programming language. They allowed task that were executed repeatedly to be collected in one
place and reused rather than being duplicated several times. In addition, procedure gave the
first possibility for information hiding.
A set of procedure written by one programmer can be used by many other programmers
without knowing the exact details of implementation. They needed only the necessary
interface.
To solve instantiation, the problem of what to do, your application needed more than
one instance of software abstraction. The key to solve this problem is ADT.
ADT is simply programmer defined data type that can be manipulated in a manner
similar to system provided data types.
This supported both information hiding as well as creating many instance of new data
type.
But message passing is not possible in ADT.
Computation As Simulation
Explain Computation as Simulation?
In Case of Object oriented Programming, Explain how do we have the view that
computation is simulation?[PU:2013 Spring]
OOP framework is different from the traditional conventional behavior of computer. Traditional
model can be viewed as the computer is a data manager, following some pattern of
instructions, wandering through memory, pulling values out of various memory transforming
them in some manner, and pushing the results back into other memory.
The behavior of a computer executing a program is a process-state or pigeon-hole model. By
examining the values in the slots, one can determine the state of the machine or the results
produced by a computation. This model may be a more or less accurate picture of what takes
place inside a computer. Real word problem solving is difficult in the traditional model.
In Object Oriented Model we speak of objects, messages, and responsibility for some action.
We never mention memory addresses, variables, assignments, or any of the conventional
programming terms. This model is process of creating a host of helpers that forms a community
and assists the programmer in the solution of a problem (Like in flower example).
The view of programming as creating a universe is in many ways similar to a style of
computer simulation called “discrete event-driven simulation”.
In, in a discrete event-driven simulation the user creates computer models of the various
elements of the simulation, describes how they will interact with one another, and sets them
moving. This is almost identical to OOP in which user describes what various entities, object in
program are, how will interact with one another and finally set them moving. Thus in OOP, we
have view that computation is simulation.
Varieties of Classes
Based on different forms of responsibility classes can be used for many different purposes and
be categorized as follows:
These type of classes generate data, such as random number generator, or that accept
data and then process them further, such as a class performing output to disk or file.
These types of classes don’t hold data for any period of time, but generates it on
demand (for a data source) or processes it when called upon (for a data sink).
Declaring structure
The struct keyword defines a structure type followed by an identifier (name of the structure).
Then inside the curly braces, you can declare one or more members (declare variables inside
curly braces) of that structure. For example:
struct Person
{
char name[50];
int age;
float salary;
};
Here a structure person is defined which has three members: name, age and salary.
Once you declare a structure person as above. You can define a structure variable as:
Person p1;
Here, a structure variable p1 is defined which is of type structure Person.
When structure variable is defined, only then the required memory is allocated by the compiler.
Considering having 16 bit system, the memory of float is 4 bytes, memory of int is 2 bytes and
memory of char is 1 byte. Hence, 56 bytes of memory is allocated for structure variable p1.
C++ Program to assign data to members of a structure variable and display it.
#include <iostream>
using namespace std;
struct Person
{
char name[50];
int age;
float salary;
};
int main()
{
Person p1;
cout << "Enter Full name: ";
cin.get(p1.name, 50);
cout << "Enter age: ";
cin >> p1.age;
cout << "Enter salary: ";
cin >> p1.salary;
cout << "Displaying Information." << endl;
cout << "Name: " << p1.name << endl;
cout <<"Age: " << p1.age << endl;
cout << "Salary: " << p1.salary;
return 0;
}
Output
Enter Full name: Ram karki
Enter age: 24
Enter salary: 25000.35
Displaying Information.
Name: Ram karki
Age: 24
Salary: 25000.35
To read the text containing blank space, cin.get function can be used. This function takes two
arguments.
First argument is the name of the string (address of first element of string) and second
argument is the maximum size of the array.
Declaration of class
Class declaration describes the type and scope of its members. The general form of class
declaration is:
class class_name
{
private:
variable declaration;
function declaration;
public:
variable declaration;
function declaration;
};
Example:
class student
{
private:
char name[20];
int roll;
public:
void getinfo();
void display();
};
#include<iostream>
using namespace std;
class student
{
private:
char name[20];
int roll;
public:
void getinfo()
{
cout<<"Enter name"<<endl;
cin>>name;
cout<<"Enter Rollno"<<endl;
cin>>roll;
}
void display()
{
cout<<"Name:"<<name<<endl;
cout<<"Roll No:"<<roll<<endl;
}
};
Objects:
An Object is an instance of a Class. When a class is defined, no memory is allocated but when it
an object is created memory is allocated. To use the data and access functions defined in the
class, we need to create objects.
class_name object_name;
e.g.
Student st; // here Student is assumed to be a class name
The statement student st; creates a variable st of type Student. This variable st is known as
object of the class Student. Thus, class variables are known as objects.
Once we have defined a class, it exists all the time a program is running whereas objects
may be created and destroyed at runtime.
For single class there may be any number of objects.
A class has unique name, attributes, and methods. An object has identity, state, and
behavior.
Accessing the class member
The data member functions of class can be accessed using the dot(.) operator with the object.
For example if the name of object is st and you want to access the member function with the
name getInfo() then you will have to write st.getinfo();
The public data members are also accessed in the same way given however the private data
members are not allowed to be accessed directly by the object. Accessing a data member
depends solely on the access control of that data member. This access control is given
by Access modifiers in C++.
Defining Member function inside the class Defining Member function Outside the class definition
definition
In this case, a member function is defined at In this technique, only declaration is done within class
the time of its declaration. The function body. The member function that has been declared
declaration is replaced by the function inside a class has to be defined separately outside the
definition inside the class body. class. The syntax for defining the
member function is as
return_type class_name::function_name(argument_list)
{
//function body
}
Here, membership label class-name :: tells the compiler
that the function function_name belongs to the class
class-name. The symbol :: is called scope resolution
operator.
#include<iostream> #include<iostream>
using namespace std; using namespace std;
class Item class Item
{ {
private: private:
int number; int number;
float cost; float cost;
public: public:
void getdata() void getdata();
{ void display();
cout<<"Enter the Item number"<<endl; };
cin>>number; void Item::getdata()
cout<<"Enter the cost of item"<<endl; {
cin>>cost; cout<<"Enter the Item number"<<endl;
} cin>>number;
void display() cout<<"Enter the cost of item"<<endl;
{ cin>>cost;
cout<<"Item number="<<number<<endl; }
cout<<"Cost of item="<<cost<<endl; void Item::display()
} {
}; cout<<"Item number="<<number<<endl;
cout<<"Cost of item="<<cost<<endl;
}
In this example, the functions getdata() and In this example, getdata() and putdata() functions are
putdata() are defined within body of class member functions of class item. They are
item. declared within class body and they are defined outside
the class body. While defining member
functions, item:: (membership identity label) specifies
that member functions belong to the class
item. Other are similar to normal function definition.
Several different classes can use the same function name (function overloading). The
membership level will resolve their scope.
Member functions can access the private data of the class. A non-member function
cannot do so.
A member function can call another member function directly, without using the dot
operator.
A private member function cannot be called by other function that is not a member of
its class.
#include<iostream>
using namespace std;
class Largest
{
private:
int a,b;
public:
void getnumber();
int compare();
void display();
};
void Largest::getnumber()
{
cout<<"Enter two number"<<endl;
cin>>a>>b;
}
int Largest::compare()
{
if (a>b)
return a;
else
return b;
}
void Largest::display()
{
cout<<"Largest number="<<compare();
}
int main()
{
Largest l;
l.getnumber();
l.display();
return 0;
}
Assignment:
Write a program that will demonstrate nested member function. The program that uses the
following properties - class name- Addnumber, integer type private member variable- a, b;
three member function -inputnumber(), int add(), show(). add() function will add the inputted
value a, b like int x=a+b. show() function will call the add() function as a nested function and
will display the addition value y as output.
#include<iostream>
using namespace std;
class sample
{
private:
int m;
void read();
public:
void update();
void display();
};
void sample::read()
{
cout<<"Enter the value of m"<<endl;
cin>>m;
}
int main()
{
sample s1;
s1.update();
s1.display();
return 0;
}
Assignment
Write a program that will demonstrate private member function. The program that uses the
following properties - class name- sum, integer type private member variable- x, y. One private
member function getnumber(), two public member function - int addition(), display(). addition()
function will call private member function getnumber() for input number x, y and add the
inputted value x, y like int z=x+y. display() function will display the addition value z as output.
Array of object
An object of class represents a single record in memory, if we want more than one record of
class type, we have to create an array of object. As we know, an array is a collection of similar
date type, we can also have arrays of variables of type class. Such variables are called array of
object. First we define a class and then array of objects are declared. An array of objects is
stored inside the memory in the same way as multidimensional array.
#include<iostream>
using namespace std;
class Employee
{
char name[25];
int age;
float salary;
public:
void getdata();
void display();
};
Another Example
Program to perform addition of two complex numbers by passing object as arguments.
#include<iostream>
#include<conio.h>
using namespace std;
class complex
{
private:
int real, imag;
public:
void getcomplex();
void addcomplex(complex, complex);
void display();
};
Output:
For first complex number
Enter real part:
2
Enter imaginary Part:
4
For second complex number
Enter real part:
1
Enter imaginary Part:
8
Sum of two complex number=3+12i
#include<iostream>
using namespace std;
class complex
{
private:
int real;
int imag;
public:
void getdata();
complex addcomplex(complex,complex);
void display();
};
void complex::getdata()
{
cout<<"Enter the real part:"<<endl;
cin>>real;
cout<<"Enter the imaginary part :"<<endl;
cin>>imag;
}
void complex::display()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
complex complex::addcomplex( complex c1, complex c2)
{
complex temp;
temp.real=c1.real+c2.real;
temp.imag=c1.imag+c2.imag;
return temp;
}
WAP to perform the addition of distance with feet and inches returning object as argument.
#include<iostream>
using namespace std;
class dist
{
private:
int feet;
int inch;
public:
void getdata();
dist add(dist,dist);
void display();
};
void dist::getdata()
{
cout<<"Enter feet:"<<endl;
cin>>feet;
cout<<"Enter inch:"<<endl;
cin>>inch;
}
void dist::display()
{
cout<<feet<<"feet and"<<inch<<"inches"<<endl;
}
int main()
{
dist d1,d2,d3,result;
cout<<"Enter information of first distance"<<endl;
d1.getdata();
cout<<"Enter information of second distance"<<endl;
d2.getdata();
result=d3.add(d1,d2);
cout<<"sum of distance=";
result.display();
return 0;
}
Assignment:
WAP to perform the addition of time in hours, minutes and seconds format.
WAP to perform the addition of time using the concept of returning object as argument.
WAP to create two distance objects with data members feet, inches and a function call
by one object passing second object as function argument and return third object
adding two objects. Hint:d3=d1.adddistance(d2);
Member function 1
Memory created when
functions are defined
Friend function
The private member of a class cannot be accessed from outside the class i.e. a nonmember
function cannot access to the private data of a class. But may be in some situation one class
wants to access private data of second class and second wants to access private data of first
class, or may be an outside function wants to access the private data of a class. However, we
can achieve this by using friend functions.
The non-member function that is “friendly” to a class, has full access rights to the private
members of the class.
To make an outside function friendly to a class, we have to declare this function as a friend
function. Declaration of friend function should be preceded by the keyword friend.
The friend function declares as follows:
class ABC
{
------
------
public :
------
------
friend void xyz(void) ; //declaration
};
We give a keyword friend in front of any members function to make it friendly.
#include <iostream>
using namespace std;
class class2;
class class1
{
private:
int x;
public:
void setvalue (int num)
{
x=num ;
}
friend void max (class1, class2);
};
class class2
{
private:
int y ;
public:
void setvalue(int num)
{
y=num ;
}
friend void max(class1, class2) ;
};
#include <iostream>
using namespace std;
class ABC; // Forward declaration
class XYZ
{
private:
int x;
public:
void setdata (int num)
{
x=num ;
}
friend void add (XYZ,ABC);
};
class ABC
{
private:
int y ;
public:
void setdata (int num)
{
y=num ;
}
friend void add(XYZ,ABC) ;
};
Output:
Sum=35
Alternative solution
#include <iostream>
using namespace std;
class ABC; // Forward declaration
class XYZ
{
public:
int x;
void getdata ()
{
cout<<"Enter Value of class XYZ"<<endl;
cin>>x;
}
friend void add (XYZ,ABC);
};
class ABC
{
int y ;
public:
void getdata ()
{
cout<<"Enter the value of class ABC"<<endl;
cin>>y;
}
friend void add(XYZ,ABC) ;
};
#include <iostream>
using namespace std;
class ABC; // Forward declaration
class XYZ
{
private:
int x;
public:
void getdata ()
{
cout<<"Enter Value of class XYZ"<<endl;
cin>>x;
}
void display()
{
cout<<"value1="<<x<<endl;
}
friend void swap (XYZ &,ABC &);
};
class ABC
{
private:
int y ;
public:
void getdata ()
{
cout<<"Enter the value of class ABC"<<endl;
cin>>y;
}
int main( )
{
XYZ p;
ABC q;
p.getdata() ;
q.getdata() ;
cout<<"Value before swapping"<<endl;
p.display();
q.display();
swap(p,q);
cout<<"Value after swapping"<<endl;
p.display();
q.display();
return 0;
}
Friend class
We can declare all the member functions of one class as the friend functions of another class. In
such cases, the class is called friend class. A friend class can use all the data member of
a class for which it is friend. For example
class B;
class A
{
…….
friend class B;
};
Here, class B can use all the data member of class A.
#include<iostream>
using namespace std;
class B; //forward declaration
class A
{
int x,y;
public:
void getdata()
{
cout<<"Enter the value of x and y:"<<endl;
cin>>x>>y;
}
friend class B;
};
class B
{
int z;
public:
void getdata()
{
cout<<"Enter the value of z:";
cin>>z;
}
void sum(A t)
{
cout<<"Sum of x,y and z ="<<(t.x+t.y+z)<<endl;
}
};
int main()
{
A p;
B q;
p.getdata();
q.getdata();
q.sum(p);
return 0;
}
A function is made inline by using a keyword inline before the function definition. Inline
functions must be defined before they are called.
Example
#include<iostream>
#include<conio.h>
using namespace std;
inline int max(int a, int b)
{
return (a>b)?a:b;
}
int main()
{
int x,y;
cout<<"Enter x and y:"<<endl;
cin>>x>>y;
cout<<"Maximum value is:"<<max(x,y);
getch();
return 0;
}
Note:
Some of the situations where inline expansion may not work are
For functions returning values, if a loop, a switch or a goto exists.
For functions not returning values, if a return statement exists.
If function contain static variables.
If inline functions are recursive.
Static member variable of a class is initialized to zero when the first object of its class is
created.
Only one copy of that member is created for the entire class and is shared by all the
objects of that class, no matter how many object are created.
It is visible only within the class but its life time is the entire program.
The type and scope of each static member variable must be defined outside the class definition.
Static variables are normally used to maintain values common to the entire class. For example,
a static data member can be used as a counter that records the occurrences of all the objects.
Example:
#include <iostream>
using namespace std;
class item
{
static int count ; // static member variable
int number ;
public:
void getdata (int a)
{
number=a;
count++ ;
}
void displaycount()
{
cout<<"count:"<<count<<endl;
}
};
int item ::count; //static member definition
Output:
Count:0
Count:0
Count:0
After reading data
Count:3
Count:3
Count:3
Output:
Count=2
Count=3
Code=1
Code=2
Code=3
Example:
#include<iostream>
using namespace std;
int main()
{
float total=100;
float &sum=total;
cout<<"Total="<<total<<endl;
cout<<"Sum="<<sum<<endl;
total=total+100;
cout<<"Total="<<total<<endl;
cout<<"Sum="<<sum<<endl;
return 0;
}
Output:
Total=100
Sum=100
Total=200
Sum=200
In the above example, we are creating a reference variable ‘sum’ for an existing variable
‘total’. Now these can be used interchangeably. Both of these names refer to same data
object in memory. If the value is manipulated and changed using one name then it will
change for another also. Eg- the statement
total = total + 100; will change value of ‘total’ to 200. And it will also change for
‘sum’. So the statements
cout<<total;
cout<<sum; both will print 200. This is because both the variables use same data object
in memory.
#include<iostream>
using namespace std;
void fun(int &x);
int main()
{
int m;
m=10;
fun(m);
cout<<"Updated value="<<m;
return 0;
}
void fun(int &x)
{
x=x+10;
}
When the function call fun(m) is executed, the following initialization occurs:
int &x=m;
Thus x becomes an alias of m after executing the statement.
fun(m);
such function calls are known as call by reference. Since the variables x and m are aliases, when
the function increments x, m is also incremented. The value of m becomes 20 after the function
is executed.
Note:
Default argument are useful in situations where some arguments always have the same
value. Eg. bank interest may remain the same for all customers for a particular period of
deposit.
Only the trailing arguments can have default values and therefore we must add defaults
from right to left.
We cannot provide a default value to a particular argument in the middle of an
argument list.
Output:
Sum=30
Sum =18
Sum =10
Sum =6
State
State tells us about the type or the value of that object.
It tells, “What the objects have?”
Example: Student have a first name, last name, age, etc...
An objects state is defined by the attributes (i.e. data members or variables) of the
object.
In OOP state is defined as data members.
It is determined by the values of its attributes.
Responsibility of Object
An object must contain the data (attributes) and code (methods) necessary to perform any and
all services that are required by the object. This means that the object must have the capability
to perform required services itself or at least know how to find and invoke these services.
Rather than attempt to further refine the definition, take a look at an example that illustrates
this responsibility concept.
Consider standalone application when looking for an example to illustrate object responsibility.
One of my favorite examples is that of a generic paint program that allows a user to select a
shape from a pallet and then drag it to a canvas, where the shape is dropped and displayed.
From the user's perspective, this activity is accomplished by a variety of mouse actions. First, the
user hovers over a specific shape with the mouse (perhaps a circle), right clicks, drags the shape
to a location on the canvas and then lifts his/her finger off the mouse.
This last action causes the shape to be placed at the desired location. In fact, what is really
happening when our user's finger is lifted from the mouse button? We can use this action to
illustrate our object responsibility concept.
This model has a major implication. Because the mouse does not need to know anything about
specific shape objects, all it needs to do to draw a shape is to send the message draw. Actually,
this will take the form of a method called draw( ). Thus, more shapes can be added without
having to change any of the mouse's behavior. The only constraint is that any shape object
installed in the application must implement a draw( ) method. If there is no draw( ) method, an
exception will be generated when the mouse mouse-up action attempts to invoke the object's
non-existent draw( ) method. In this design methodology, there is a de facto contract between
the mouse class and the shape class and these contracts are made possible by the powerful
object-oriented design technique called polymorphism.
1) Declare a C++ structure (Program) to contain the following piece of information about
cars on a used car lot: [PU:2013 spring]
i. Manufacturer of the car
ii. Model name of the car
iii. The asking price for the car
iv. The number of miles on odometer
2) Differentiate between class and structure. Explain them with example.[PU:2010 spring]
3) What sorts of shortcomings of structure are addressed by classes? Explain giving
appropriate example.[PU:2014 fall]
4) Differentiate between structure and class. Why Class is preferred over structure?
Support your answer with suitable examples.[PU:2016 fall]
5) Explain the various access specifiers used in C++ with an example.
[PU:2010 fall][PU:2016 spring]
6) What is information hiding? What are the access mode available in C++ to implement
different levels of visibility? Explain through example.[PU:2014 spring][PU:2016 fall]
1. Declare a C++ structure (Program) to contain the following piece of information about
cars on used car lot. [PU:2013 spring]
2. Create a class called Employee with three data members (empno , name, address), a
function called readdata() to take in the details of the employee from the user, and a
function called displaydata() to display the details of the employee. In main, create two
objects of the class Employee and for each object call the readdata() and the
displaydata() functions. [PU:2005 fall]
3. Create a class called student with three data members
(stdnt_name[20],faculty[20],roll_no), a function called readdata() to take the details of
the students from the user and a function called displaydata() to display the details the
of the students. In main, create two objects of the class student and for each object call
both of the functions. [PU:2010 fall]
4. Modify the Que.no 2 for 20 students using array of object.
5. WAP to perform the addition of time in hours, minutes and seconds format.
6. WAP to perform the addition of time using the concept of returning object as argument.
7. WAP to create two distance objects with data members feet, inches and a function call
by one object passing second object as function argument and return third object
adding two objects. Hint:d3=d1.adddistance(d2);
8. Create a class called Rational having data members nume and deno and using friend
function find which one is greater.
9. WAP to add the private data of three different classes using friend function.
10. Write a program to find the largest of four integers .your program should have three
classes and each classes have one integer number.[PU:2014 spring]
11. WAP to swap the contents of two variables of 2 different classes using friend function.
12. WAP to add two complex numbers of two different classes using friend function.
13. WAP to add complex numbers of two different classes using friend class.
14. Using class write a program that receives inputs principle amount, time and rate.
Keeping rate 8% as the default argument, calculate simple interest for three
customers.[PU:2019 fall]
There are three identifiable parts to any message-passing expression. These are
1) Receiver: the object to which the message is being sent
2) Message selector: the text that indicates the particular message is being sent.
3) Arguments used in responding the message.
s.getdata(100,200);
In a message passing there is a designated receiver for that message; the receiver is
some object to which message is sent.
Interpretation of the message (that is method is used to respond the message) is
determined by the receiver and can vary with different receivers. That is, different
object receive the same message and yet perform different actions.
Usually, the specific receiver for any given message will not be known until run time, so
determination of which method cannot be made until then. Thus, we say there is a late
binding between the message (function or procedure name) and the code fragment
(method) used to respond to the message.
Procedure calls
Constructor
A constructor is a special member function which initializes the objects of its class. It is
called special because its name is same as that of the class name.
The constructor is automatically executed whenever an object is created. Thus, a
constructor helps to initialize the objects without making a separates call to a member
function.
It is called constructor because it constructs values of data members of a class.
Types of Constructor:
1. Default constructor
Program:
#include <iostream>
using namespace std;
class Complex
{
private:
int real,imag ;
public:
Complex()
{
real=0;
imag=0;
}
void display( )
{
cout<<"Real part="<<real<<endl;
cout<<"Imaginary part="<<imag<<endl ;
}
};
int main( )
{
Complex c1;
c1.display();
return 0;
}
Output:
Real part=0
Imaginary Part=0
The constructor that can take arguments are called parameterized constructor.
Arguments are passed when the objects are created. This can be done in two ways.
by calling the constructor explicitly
by calling the constructor implicitly
For example, the constructor used in the following example is the parameterized constructor
and takes two arguments both of type int.
class Complex
{
private:
int real,imag;
public:
Complex (int r, int i) //parameterized constructor
{
real=r;
imag=i;
}
.......
.......
};
int main()
{
Complex c1(5,2); //implicit call
Complex c2 =Compex(7,4); //explicit call
........
}
#include <iostream>
using namespace std;
class Complex
{
private:
int real,imag;
public:
Complex(int r,int i)
{
real=r;
imag=i;
}
void display( )
{
cout<<"Real part="<<real<<endl;
cout<<"Imaginary part="<<imag<<endl ;
}
};
int main( )
{
Complex c1(5,2);
c1.display();
return 0;
}
Output:
Real part=5
Imaginary part=2
3) Copy Constructor
A copy constructor is used to declare and initialize an object with another object of
the same type.
For example, the statement
Complex c2(c1);
Creates new object c2 and performs member-by-member copy of c1 into c2. Another
form of this statement is
Complex c2 = c1;
When no copy constructor is defined, the compiler supplies its own copy constructor.
#include<iostream>
using namespace std;
class Complex
{
private:
int real, imag ;
public:
Complex( )
{
}
Complex (int r,int i)
{
real=r ;
imag=i ;
}
Complex (Complex &x)
{
real=x.real ;
imag=x.imag ;
}
void display( )
{
cout<<"Real part="<<real<<endl;
cout<<"Imaginary part="<<imag<<endl;
}
};
Constructor Overloading
We can have more than one constructor in a class with same name and different number of
arguments. This concept is known as Constructor Overloading.
Overloaded constructors essentially have the same name (name of the class) and different
number of arguments.
A constructor is called depending upon the number and type of arguments passed.
While creating the object, arguments must be passed to let compiler know, which
constructor needs to be called.
#include<iostream>
using namespace std;
class Complex
{
int real,imag;
public:
Complex() //Default Constructor
{
real=0;
imag=0;
}
Complex(int r,int i) //Parameterized Constructor
{
real=r;
imag=i;
}
void display()
{
cout<<"Real part:"<<real<<endl;
cout<<"Imaginary part"<<imag<<endl;
}
};
int main()
{
Complex c1;
Complex c2(5,2);
Complex c3(c2);
c1.display();
c2.display();
c3.display();
return 0;
}
In the above example of class Complex, we have defined three constructors. The first one is
invoked when we don’t pass any arguments. The second gets invoked when we supply
two argument, while the third one gets invoked when an object is passed as an argument.
Example
Complex c1;
This statement would automatically invoke the first one.
Complex c2(102,300); invokes 2nd constructor
Complex c3(c2); invokes 3rd constructor
#include<iostream>
using namespace std;
class test
{
int a,b,c;
public:
test(int x=1,int y=2,int z=3);
void display();
};
test::test(int x,int y,int z)
{
a=x;b=y;c=z;
}
void test::display()
{
cout<<"a="<<a<<"b="<<b<<"c="<<c<<endl;
}
int main()
{
test t1;
test t2(5,10,15);
test t3(6);
t1.display();
t2.display();
t3.display();
return 0;
}
Output:
a=1b=2 c=3
a=5b=10 c=15
a=6b=2 c=3
Destructors
Destructor is a member function that destroys the object that have been created by a
constructor.
Destructor name is similar to class name but preceded by a tilde sign (~).
They are also defined in the public section.
Destructor never takes any argument, nor does it return any value. So, they cannot be
Overloaded.
Example:
A destructor for the class test will look like
~test()
{
------
------
}
#include<iostream>
using namespace std;
class test
{
static int count;
public:
test()
{
count++;
cout<<"object:"<<count<<"created"<<endl;
}
~test()
{
cout<<"object:"<<count<<"destroyed"<<endl;
count--;
}
};
int test::count;
int main()
{
cout<<"Inside the main block"<<endl;
test t1;
{
//Block 1
cout<<"Inside Block 1"<<endl;
test t2,t3;
cout<<"Leaving Block 1"<<endl;
}
cout<<"Back to main Block"<<endl;
return 0;
}
Similarly,
Syntax: pointer-variable = new data-type [size];
This one is used to allocate a block (an array) of elements of type data-type,
where size is an integer value representing the number of elements.
For Example:
int *ptr;
*ptr = new int [5];
Syntax is:
delete pointer-variable;
delete [size] pointer-variable;
The first statement releases the memory of a single element allocated using new
The second one releases the memory allocated for arrays of elements using new and a
size in brackets ([ ]).
Note: The size specifies the number of elements in the array to be freed. The problem with this
form is that programmer should remember the size of the array. Recent version of c++ do not
require the size to be specified. for example,
delete[] ptr;
#include <iostream>
using namespace std;
int main ()
{
int i,size;
int *ptr;
cout << "How many numbers would you like to Enter? ";
cin >>size;
ptr= new int[size];
for (i=0; i<size; i++)
{
cout << "Enter number:"<<i+1<<endl;
cin >> ptr[i];
}
cout << "You have entered:"<<endl;
for (i=0; i<size; i++)
{
cout << ptr[i]<<endl ;
}
delete[] ptr;
return 0;
}
It's a region of computer's memory that stores temporary variables created by each
function (including the main() function).
The stack is a "Last in First Out" data structure and limited in size. Every time a function
declares a new variable, it is "pushed" (inserted) onto the stack. Every time a function
exits, all of the variables pushed onto the stack by that function, are freed or popped
(that is to say, they are deleted).
Once a stack variable is freed, that region of memory becomes available for other stack
variables.
A key to understanding the stack is the notion that when a function exits, all of its
variables are popped off (Removed) of the stack (and hence lost forever).
Advantages
Memory is managed to store variables automatically. We don't have
to allocate memory by hand, or free it once we don't need it any more.
CPU organizes stack memory so efficiently, reading from and writing to stack
variables is very fast.
Limitations
Limit (varies with OS) on the size of variables that can be store on the stack.
Heap
The heap is a region of computer's memory that is not managed automatically
and is not as tightly managed by the CPU.
Dynamic memory allocation is a way for running programs to request memory from the
operating system when needed. This memory does not come from the program’s
limited stack memory -- instead, it is allocated from a much larger pool of memory
managed by the operating system called the heap. It is a more free-floating region of
memory (and is larger).
To allocate memory on the heap, you must use new operator in C++.Once you have
allocated memory on the heap, you are responsible for using delete to de-allocate that
memory once you don't need it any more.
Unlike the stack, the heap does not have size restrictions on variable size (apart from
the obvious physical limitations of computer).
Heap memory is slightly slower to be read from and written to, because one has to use
pointers to access memory on the heap.
Stack Vs Heap
Stack Heap
1) Only Local variables can be 1) Variables can be accessed globally
accessed.
2) Limit on stack size dependent on 2) Does not have a specific limit on
OS. memory size.
3) It can access faster. 3) Relatively slower access.
We should use heap when we require to allocate a large block of memory. For example,
you want to create a large size array or big structure to keep that variable around a long
time then you should allocate it on the heap.
However, If we are working with relatively small variables that are only required until
the function using them is alive. Then we need to use the stack, which is faster and
easier.
#include<iostream>
using namespace std;
class Rectangle
{
private:
float length,breadth,area;
public:
Rectangle(float l,float b)
{
length = l;
breadth = b;
}
void calc( )
{
area= length * breadth;
}
void display( )
{
cout << "Area = " << area << endl;
}
};
int main()
{
Rectangle r(2,4);
r.calc();
r.display();
return 0;
}
2) WAP to initialize name, roll and marks of student using constructor and display then
obtained information.
#include<iostream>
#include<string.h>
using namespace std;
class Student
{
private:
char name[20];
int roll;
float marks;
#include<iostream>
#include<string.h>
using namespace std;
class student
{
private:
int roll;
float me,mm,mo,total,avg;
char name[30];
public:
student(char n[],int r,float e,float m,int o)
{
strcpy(name,n);
roll=r;
me=e;
mm=m;
mo=o;
}
void calculate()
{
total= me+mm+mo;
avg=total/3;
}
void print()
{
cout<<"Name="<<name<<endl;;
cout<<"Roll No="<<roll<<endl;;
cout<<"Total="<<total<<endl;
cout<<"Average="<<avg<<endl;
}
};
#include<iostream>
using namespace std;
class complex
{
private:
int real,imag;
public:
complex()
{
real=2;
imag=4;
}
complex(int r,int i)
{
real=r;
imag=i;
}
5) Create a class person with data members Name, age, address and citizenship number.
Write a constructor to initialize the value of the person. Assign citizenship number if
the age of the person is greater than 16 otherwise assign value zero to citizenship
number. Also create a function to display the values.[PU:2013 fall]
#include<iostream>
#include<string.h>
using namespace std;
class person
{
private:
char name[20];
char address[20];
int age;
long int citzno;
void display()
{
cout<<"Name:"<<name<<endl;
cout<<"Address:"<<address<<endl;
cout<<"Age:"<<age<<endl;
cout<<"Citizenship no:"<<citzno<<endl;
}
};
int main()
{
char name[20];
char address[20];
int age;
long int citzno;
cout<<"Enter the name"<<endl;
cin>>name;
cout<<"Enter the address"<<endl;
cin>>address;
cout<<"Enter the age"<<endl;
cin>>age;
if (age>16)
{
cout<<"Enter the citizenship number"<<endl;
cin>>citzno;
person p(name,age,address,citzno);
p.display();
}
else
{
person p(name,age,address,0);
p.display();
}
return 0;
}
#include<iostream>
#include<string.h>
using namespace std;
class Mountain
{
private:
char name[20],location[20];
float height;
public:
Mountain(char n[],float h,char l[])
{
strcpy(name,n);
height=h;
strcpy(location,l);
}
void DispInf()
{
cout<<"Name:"<<name<<endl;
cout<<"Height:"<<height<<endl;
cout<<"Location:"<<location<<endl;
}
friend void CmpHeight(Mountain,Mountain);
};
}
time(int h,int m,int s)
{
hr=h;
min=m;
sec=s;
}
void display()
{
cout<<hr<<":"<<min<<":"<<sec<<endl;
}
void sum(time,time);
};
#include<iostream>
#include<string.h>
using namespace std;
class employee
{
private:
int code;
char name[20];
char address[20];
float salary;
public:
employee(int c, char n[],char addr[],float s)
{
code=c;
strcpy(name,n);
strcpy(address,addr);
salary=s;
}
employee(employee &e)
{
code=e.code;
strcpy(name,e.name);
strcpy(address,e.address);
salary=e.salary;
}
void display()
{
cout<<"Code="<<code<<endl;
cout<<"Name="<<name<<endl;
cout<<"Address="<<address<<endl;
cout<<"Salary="<<salary<<endl;
}
};
#include<iostream>
using namespace std;
class student
{
private:
char name[20];
int roll;
float m1,m2,m3;
public:
void getdata()
{
cout<<"enter the name"<<endl;
cin>>name;
cout<<"enter the roll"<<endl;
cin>>roll;
cout<<"Enter marks of 3 subjects"<<endl;
cin>>m1>>m2>>m3;
}
int main()
{
int n,i;
student *ptr;
cout<<"Enter the number of students:";
cin>>n;
ptr= new student[n];
for(i=0;i<n;i++)
{
cout<<"Enter the information of student"<<i+1<<endl;
ptr[i].getdata();
}
for(i=1;i<=n;i++)
{
cout<<"Information of student"<<i<<endl;
ptr[i].display();
}
delete[] ptr;
return 0;
}
#include<iostream>
using namespace std;
class student
{
private:
float sub1,sub2,sub3,sub4,sub5;
public:
void getdata()
{
cout<<"Enter marks of 5 subjects"<<endl;
cin>>sub1>>sub2>>sub3>>sub4>>sub5;
}
void display()
{
if(sub1>=45&&sub2>=45&&sub3>=45&&sub4>=45&&sub5>=45)
cout<<"student is passed"<<endl;
else
cout<<"student is failed"<<endl;
}
};
int main()
{
int n,i;
student *ptr;
cout<<"Enter the number of students:";
cin>>n;
ptr= new student[n];
for(i=0;i<n;i++)
{
cout<<"Enter marks of student"<<i+1<<endl;
ptr[i].getdata();
ptr[i].display();
}
delete[] ptr;
return 0;
}
#include <iostream>
using namespace std;
int main ()
{
int i,size,sum=0;
int *ptr;
cout << "How many numbers would you like to Enter?"<<endl;
cin >>size;
ptr= new int[size];
for (i=0; i<size; i++)
{
cout << "Enter number"<<i+1<<endl;
cin >> ptr[i];
}
cout << "You have entered:"<<endl;
for (i=0; i<size; i++)
{
cout << ptr[i] << endl;
}
for (i=0; i<size; i++)
{
sum=sum+ptr[i];
}
cout<<"sum of numbers="<<sum<<endl;
delete[] ptr;
return 0;
}
General syntax :
class derived_class_name : visibility_mode base_class_name
{
//members of derived class
};
The colon (:) indicates that the derived_class_name is derived from the
base_class_name.
The visibility_mode is optional, if present, may be either private or public.
The default visibility mode is private.
Visibility mode specifies whether the features of the base class are privately derived or
publicly derived or derived on protected.
class A
{
public:
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};
class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};
1) Single Inheritance
When a class is derived from only one base class, then it is called single inheritance.
A
Base Class
B
Derived Class
General form:
Base Class A B
C
Derived Class
General form
class A
{
};
Class B
{
};
class C:public A, public B
{
};
In General form there are 3 classes A, B and C. Class A and B are base classes and C is derived
class.
All data members in protected and public of class A & B can be accessed using object of class C.
Here two base classes A and B have been created and a derived class C is created from
both base classes.
B C D
General form
class A
{
};
Class B: public A
{
};
Class C: public A
{
};
Class D: public A
{
};
In General form three classes B and C and D are derived from same base class A. All
data members in protected and public of class A can be accessed using object of
classes B, C, D.
A
Base class
B
Derived Class
General form
Class A
{
.... .. . ..
};
Class B: public A
{
. . . . . .. .
};
Class C: public B
{
............
};
In General form there are 3 classes A,B and C. Class A is base class and Class B is derived
class from Class A and class C is derived class from class B. All data members in protected and
public of class A can be accessed using object of classes B, C and of class B can be accessed by
class C.
D
B
Class A
{
};
Class D
{
};
Class B: public A
{
};
Class C: public B, Public D
{
};
Description: In General form there are 4 classes A, B, C and D. Classes A & D are base classes
and Class B is derived class from Class A and class C is derived class from classes B & D. All data
members in protected and public of class A can be accessed using object of classes B, C and of
classes B&D can be accessed by class C.
#include<iostream>
using namespace std;
class A
{
private:
int x;
protected:
int y;
public:
int z;
void get_xyz()
{
cout<<"Enter the value of x,y,z"<<endl;
cin>>x>>y>>z;
}
void show_xyz()
{
cout<<"x="<<x<<"y="<<y<<"z="<<z<<endl;
}
};
class B:public A
{
private:
int k,sum;
public:
void get_k()
{
cout<<"Enter the value of k"<<endl;
cin>>k;
}
void show_k()
{
cout<<"k="<<k<<endl;
}
void addition()
{
sum=y+z+k;
}
int main()
{
B b1;
b1.get_xyz();
b1.get_k();
b1.show_xyz();
b1.show_k();
b1.addition();
b1.display();
}
Single Inheritance: Private
#include<iostream>
using namespace std;
class A
{
private:
int x;
protected:
int y;
public:
int z;
void get_xyz()
{
cout<<"Enter the value of x,y,z"<<endl;
cin>>x>>y>>z;
}
void show_xyz()
{
cout<<"x="<<x<<"y="<<y<<"z="<<z<<endl;
}
};
class B:private A
{
private:
int k,sum;
public:
int main()
{
B b1;
b1.getdata();
b1.showdata();
b1.addition();
b1.display();
}
#include<iostream>
using namespace std;
class M
{
protected:
int m;
public:
void get_m(int x)
{
m=x;
}
};
class N
{
protected:
int n;
public:
void get_n(int y)
{
n=y;
}
};
#include<iostream>
using namespace std;
class student
{
protected:
int roll;
public:
void getnum(int x)
{
roll=x;
}
void putnum()
{
cout<<"Roll number="<<roll<<endl;
}
};
class test:public student
{
protected:
float sub1,sub2;
public:
void getmarks(float x,float y)
{
sub1=x;
sub2=y;
}
void putmarks()
{
cout<<"Marks in sub1="<<sub1<<endl;
cout<<"Marks in sub2="<<sub2<<endl;
}
};
#include<iostream>
using namespace std;
class A
{
protected:
int x,y;
public:
void init()
{
x=20;y=10;
}
};
#include<iostream>
using namespace std;
class A
{
protected:
int x;
public:
void assignx( )
{
x=20;
}
};
class B: public A
{
protected:
int y ;
public:
void assigny()
{
y=40;
}
};
class C :public B
{
protected:
int z;
public:
void assignz( )
{
z=60;
}
};
class D
{
protected :
int k ;
public:
void assignk( )
{
k=80;
}
};
When two or more than two base classes have a function of identical name and when class
inherits from multiple base classes then ambiguity occurs.
class M
{
public:
void display()
{
cout<<"Class M"<<endl;
}
};
class N
{
public:
void display()
{
cout<<"Class N"<<endl;
}
};
Which display function is used by the derived class when we inherit these two classes?
We can solve this problem by redefining the member in the derived class using resolution
operator with the function as shown below.
Class M
class B:public A
{
public:
void display()
{
cout<<"class B"<<endl;
}
};
In this case, the function in the derived class overrides the inherited function and therefore
simple call to display() by B type object will invoke function defined in B only. However, we may
invoke the function defined in A by using the scope resolution operator to specify the class.
int main()
{
B b;
b.display(); //derived class object
b.A::display(); //invokes display() in A
b.B::display(); //invokes display() in B
return 0;
}
Output:
Class B
Class A
Class B
During the time of hybrid inheritance when there is a hierarchical inheritance at the
upper level and multiple inheritance at lower level, ambiguity occurs due to the
duplication of data from multiple path at the grand child class. How this kind of
ambiguity is resolved? Explain with suitable example.[PU:2013 fall]
Does ambiguity occurs in hybrid inheritance .If yes? How can you remove this? Explain
with example.[PU:2018 fall]
Under what condition virtual base class is created? Explain it with suitable example
.[PU:2017 fall]
In the above example, both Class B and Class C inherit properties of Class A, they both have
single copy of Class A. However Class D inherit both Class B and Class C, therefore Class D have
two copies of Class A, one from Class B and another from Class C. This introduces ambiguity and
should be avoided..
The duplication of inherited members due to these multiple paths can be avoided by making
common base class as virtual class while declaring the direct or intermediate base classes.
To remove multiple copies of Class A from Class D, we must inherit Class A in Class Band Class C
as virtual class.
class A
{
----------------------
};
class B:virtual public A
{
//parent1
----------------------
};
class C:public virtual A
{
//parent2
----------------------
};
class D:public B, public C{
//child
----------------------
};
#include<iostream>
using namespace std;
class A
{
public:
int a;
};
class B : virtual public A
{
public:
int b;
};
class C : virtual public A
{
public:
int c;
};
int main()
{
D obj;
obj.a = 10; //value of obj.a is replaced by 100 due to only one copy of data member of class A
obj.a = 100; // is available in class D
obj.b = 20;
obj.c = 30;
obj.d = 40;
cout<< "A="<<obj.a<<endl;
cout<< "B="<<obj.b<<endl;
cout<< "C="<<obj.c<<endl;
cout<< "D="<<obj.d<<endl;
return 0;
}
Illustration of when base and derived class constructor and destructor functions are
executed
#include <iostream>
using namespace std;
class A
{
public:
A( )
{
cout<< "Constructor in base class"<<endl ;
}
~A( )
{
cout<< "Destructor in base class"<<endl ;
}
};
class B:public A
{
public:
B()
{
cout<< "Constructor in derived class"<<endl ;
}
~B( )
{
cout<< "Destructor in derived class"<<endl ;
}
};
int main( )
{
B obj;
return 0;
}
If the base class does not have any constructors taking arguments (parameterized
constructors), the derived class need not have a constructor function.
If the base class contains a constructor with one or more arguments then it is
mandatory for the derived class to have a constructor and pass the arguments to the
base class constructors.
When both the derived and base classes contain constructors then the base class
constructors is execute first and then the constructor in the derived class is executed.
In case of Multiple Inheritance
The base classes are constructed in the order in which they appear in the
declaration of the derived class
In case of Multilevel Inheritance
The constructors will be executed in the order of inheritance
The constructors for virtual base classes are invoked before any non-virtual base classes.
}
The header line of derived constructor function contains two parts separated by a colon (:)
The first part provide the declaration of arguments that are passed to the derived constructor
and the second part lists the function calls to the base constructors
Here, base1(Arglist1), base2(Arglist2)….. baseN (ArglistN) are function calls to base class
constructors and Arglist1, Arglist2…… ArglistN are the actual parameters that are passed to the
base constructors . Here, ArglistD provides the parameters that are necessary to initialize the
members of the derived class itself.
Example:
#include<iostream>
using namespace std;
void showg()
{
cout<<"z="<<z<<endl;
}
};
Output:
Beta is initialized
Alpha is initialized
Gamma is initialized
Here, beta is initialized first although it appears second in the derived constructor as it has been
declared first in the derived class header line
class gamma: public beta, public alpha
{
}
If we change the order to
class gamma: public alpha, public beta
{
}
then alpha will be initialized first
int main()
{
beta b1(3,4);
b1.showa();
b1.showb();
return 0;
}
#include<iostream>
using namespace std;
class alpha
{
private:
int a;
public:
alpha(int x)
{
a=x;
}
void showa()
{
cout<<"value of a="<<a<<endl;
}
};
int main()
{
gamma g1(5,6,7,10,20);
g1.showa();
g1.showb();
g1.showc();
return 0;
}
#include<iostream>
using namespace std;
class alpha
{
private:
int a;
public:
alpha(int x)
{
a=x;
}
void showa()
{
cout<<"value of a="<<a<<endl;
}
};
class beta
{
private:
int b,c ;
public:
beta(int y,int z)
{
b=y;
c=z;
}
int main()
{
gamma g1(5,6,7,10,20);
g1.showa();
g1.showb();
g1.showc();
return 0;
}
#include<iostream>
using namespace std;
class alpha
{
private:
int a,b,c;
public:
alpha(int x,int y,int z):a(x),b(2*y)
{
c=z;
}
void showa()
{
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
cout<<"c="<<c<<endl;
}
};
Instances of the child class must possess all data members associated with the parent
class.
Instances of the child class must implement, through inheritance as least (if not
explicitly overridden), all functionality defined for parent class. (They can also define
new functionality)
The instance of a child class can mimic the behavior of parent class and should be
indistinguishable from an instance of parent class if substituted in similar situation.
The Principal of Substitutability
It states that “If we have two classes A and B such that class B is a subclass of A, it should be
possible to substitute instances of class B for instances of class A in any situation with no
observable effect”
The term subtype is used to refer to a subclass relationship in which the principle of
substitutability is maintained to distinguish such forms from the general subclass relationship,
we may or may not satisfy this principle.
In the example below the class B object is replaced by the object of class A without any error.
This is achieved when a child class is inherited from a base class publicly. In the same example,
if the mode of inheritance is made private the base class object ‘a’ can’t be replaced by the
parent class object ‘a’.
EXAMPLE:
#include<iostream>
using namespace std;
class A
{
public:
void display()
{
cout <<"class A";
}
};
Containership/Composition
When a class contains object of another class as its member data, it is termed as
containership. The class which contains the object is called container class. Containership
is also termed as “class within class”.
class A
{
……
……
};
class B
{
…..
A obj1;
…..
};
Here, class B contains object of class A. so that B is the container class.
#include<iostream>
using namespace std;
class Employee
{
int eid;
float salary;
public:
void getdata()
{
cout<<"Enter id and salary of employee"<<endl;
cin>>eid>>salary;
}
void display()
{
cout<<"Emp ID:"<<eid<<endl;
cout<<"Salary:"<<salary<<endl;
}
};
class Company
{
char cname[20];
char department[20];
Employee e;
public:
void getdata()
{
e.getdata();
cout<<"Enter company name and Deparment:"<<endl;
cin>>cname>>department;
}
void display()
{
e.display();
cout<<"Company name:"<<cname<<endl;
cout<<"Department:"<<department<<endl;
}
};
};
}
5. Inheritance leads tight coupling 5. In Composition relationship between
between superclass and subclass. class can be decoupled easily .so it is
6. So it is harder to maintain in future. can be easily maintained in future.
Software reusability
Software reusability is the practice of using existing code for a new software. But in order to
reuse code, that code needs to be high-quality. And that means it should be safe, secure,
reliable, efficient and maintainable.
In OOP, the concept of inheritance provide the idea of reusability. This means that we can add
additional features to an existing class without modifying it. This is possible by deriving a new
class from the existing one. The new class will have the combined features of both the classes.
Reusability can be provided through the concept of composition also. In composition one class
contains the object of another classes to make it as a whole.
Forms of Inheritance
1. Subclassing for specialization
The new class is a specialized form of the parent class but satisfies the specifications of
the parent class in all relevant aspects.
Example:
Window
DTextEditWindow
Window class provides the general windowing operations (moving, resizing, iconification
and so on).
The specialized subclass TextEditWindow inherits the window operations and in
addition provides the facilities that allow window to display textual material and user to
edit the text values.
Here class maintains the common interface (they implement the same methods).
The parent class can be a combination of implemented operations and
operations that are deferred to the child classes.
There is no interface change as the child implements the behavior described but
not implemented in parent.
Here a class can often inherit almost all of its desired functionality from a parent class,
perhaps changing only names of the methods used to interface to the class or modifying
the arguments in a certain fashion.
Consider a graphics display system in which a class Window has been defined for
displaying on a simple black-and-white background. We could create a subtype
ColoredWindow that lets the background color to be something other than white by
adding an additional field to store the color and overriding the inherited window display
code that specifies the background be drawn in that color.
The child class adds the new functionality to the parent class but does not
change any inherited behavior.
Subclassing for generalization modifies or expands on the existing functionality
of an object whereas subclassing for extension add totally new abilities.
The child class restricts the use of some of the behaviors inherited from the
parent class.
Subclassing for limitation occurs when the behavior of subclass is smaller or
more restrictive than the behavior of the parent class.
For example ,an existing class library provides the double-ended queue or deque, data
structure. Elements cab be added or removed form either end of the deque, but a
programmer wishes to write stack class, enforcing the property that elements can be
added to removed from only one end of the stack.
Subclassing for variance is employed when two or more classes have similar
implementations but do not seem to posses any hierarchical relationships between
the abstract concept represented by the classes.
Example
Code required to control the mouse may be nearly identical to the code required to
control the graphics tablet. Conceptually there is no reason why class mouse should be
made the subclass of class GraphicsTablet.
A better alternative is to factor out the common code into an abstract class, say
PointingDevice and to have both classes inherit from this parent classes.
Here, the subclass represents the combination of features from two or more parent
classes .Eg. A teaching assistant may have characteristic of both teacher and
student. This is multiple inheritance.
Inheritance is used in variety ways according to user’s requirements. The Following are
forms of inheritance.
1) Sub classing for specialization: The child class is the special case of the parent class; in
other words the child class is a subtype of parent class.
2) Sub classing for specification: The parent class defines behavior that is implemented in
child class but not in parent class.
3) Sub classing for construction: The child class makes use of behavior provided by the
parent class but is not a subtype of parent class.
4) Sub classing for generalization: The child class modifies or overrides some of the
methods of the parent class but is not a subtype of parent class.
5) Sub classing for extension: The child class adds new functionality to the parent class but
does not change any inherited behavior.
6) Sub classing for limitation: The child class restricts the use of some of the behavior
inherited from parent class.
7) Sub classing for variance: The child class and parent class are variants of each other and
the class-subclass relationship is arbitrary.
8) Sub classing for combination: The child class inherits features from more than one
parent class. This is multiple inheritance.
#include<iostream>
#include<string.h>
using namespace std;
class first
{
char name[20];
public:
void setn(char n[])
{
strcpy(name,n);
}
char* getn()
{
return (name);
}
};
class second
{
char address[20];
public:
void seta(char a[])
{
strcpy(address,a);
}
char* geta()
{
return (address);
}
};
class concat
{
private:
first f;
second s;
public:
void getinfo(char n[],char a[])
{
f.setn(n);
s.seta(a);
}
int main()
{
concat c;
c.getinfo("Ram","kathmandu");
c.join();
return 0;
}
Alternative solution:
#include<iostream>
#include<string.h>
using namespace std;
class first
{
string name;
public:
void setn(string n)
{
name=n;
}
string getn()
{
return (name);
}
};
class concat
{
private:
string tn,ta;
first f;
second s;
public:
void getinfo( string a,string b)
{
f.setn(a);
s.seta(b);
}
void join()
{
tn=f.getn();
ta=s.geta();
tn=tn+ta;
cout<<"name+address:"<<tn;
}
};
int main()
{
concat c;
c.getinfo("Ram","Kathmandu");
c.join();
return 0;
}
#include<iostream>
#include<string.h>
using namespace std;
class Person
{
private:
char name[20];
int age;
char address[20];
public:
Person(char n[],int a,char addr[])
{
strcpy(name,n);
age=a;
strcpy(address,addr);
}
void showdata()
{
cout<<"Name:"<<name<<endl;
cout<<"Age:"<<age<<endl;
cout<<"Address:"<<address<<endl;
}
};
class Teacher:public Person
{
char qualification[20];
char department[20] ;
public:
Teacher(char n[],int a,char addr[],char q[],char d[]):Person(n,a,addr)
{
strcpy(qualification,q);
strcpy(department,d);
}
{
strcpy(program,p);
sem=s;
}
void showdata()
{
cout<<"Program:"<<program<<endl;
cout<<"Semester:"<<sem<<endl;
}
};
int main()
{
Teacher t("Hari",32,"Kathmandu","Master","Civil");
Student s("Ram",24,"Pokhara","Computer",2);
cout<<"Information of Teacher is"<<endl;
t.Person::showdata();
t.showdata();
cout<<"Information of Student is"<<endl;
s.Person::showdata();
s.showdata();
return 0;
}
The class Record derives the information from both Account and Admin classes and in
turn derive information from the class Person .Define all the four classes with at least
one parameterixed constructor and ‘void display’ method in each class.In main()
function create a object of class ‘Record’ and initialize all data members and display
them.[PU:2015 spring]
#include<iostream>
#include<string.h>
using namespace std;
class Person
{
private:
char name[20];
int code;
public:
Person(char n[],int c)
{
strcpy(name,n);
code=c;
}
void display()
{
cout<<"Name="<<name<<endl;
cout<<"Code="<<code<<endl;
}
};
void display()
{
cout<<"No of experience year="<<year<<endl;
}
};
class Record:public Account,public Admin
{
private:
int recno;
public:
Record(char n[],int c,float s,int y,int r):Account(n,c,s),Admin(n,c,y),Person(n,c)
{
recno=r;
}
void display()
{
cout<<"Record no="<<recno<<endl;
}
};
4) Write a base class that ask the user to enter time(hour,minute and second) and
derived class adds the time of its own with the base.Finally make third class that is
friend of derived and calculate the difference of base time and is own time.[PU:2017
fall]
#include<iostream>
using namespace std;
class time1
{
protected:
int hr1,min1,sec1;
public:
void getdata1()
{
cout<<"Enter hour,minute and second for base class"<<endl;
cin>>hr1>>min1>>sec1;
}
void display1()
{
cout<<hr1<<"hours"<<min1<<"minutes"<<sec1<<"seconds"<<endl;
}
};
INHERITANCE
1. “Inheritance allows us to create a hierarchy of classes. Justify this statement. Discuss
private and public inheritance.[PU:2016 spring]
2. How does visibility mode control the access of members in the derived class? Explain
with an example.[PU 2017 spring]
3. Explain hybrid inheritance with example.[2009 spring]
4. What is hybrid Inheritance. Explain any three pros and three cons of inheritance.
[PU: 2010 fall]
5. How inheritance support reusability features of OOP? Explain with example.[PU:2010
spring]
6. When base class and derived class have the same function name what happens when
derived class object calls the function?[PU 2017 fall]
7. Explain how inheritance support Reusability? Describe the syntax of multiple and
multilevel inheritance?[PU:2015 fall]
8. Inheritance supports characteristic of OOP. Justify your answer. Explain ambiguity that
occurs in multiple inheritance.[PU:2017 spring]
9. “Ambiguity is essential evil” ”,Explain by example how it can effectively solve in complex
programming?[PU: 2015 spring]
10. Explain why multiple inheritance is dangerous?
11. During the time of hybrid inheritance when there is hierarchical inheritance at the upper
level and multiple inheritance at lower level, ambiguity occurs due to the duplication of
data from multiple path at the grand child class. How this kind of ambiguity is resolved?
Explain with suitable example?
12. Does ambiguity occurs in hybrid inheritance? If yes, how can you remove this? Explain
with an example.[PU 2018 fall]
13. Under what condition virtual base class is created? Explain with suitable
example.[PU:2017 fall,2019 fall,2014 fall]
14. How are arguments are sent to base constructors in multiple inheritance ?Who is
responsibility of it.[PU:2013 spring]
15. How does inheritance influence working of constructors and destructors? Class ‘Y’ has
been derived from class ‘X’ .The class ‘Y’ does not contain any data members of its own.
Does the class ‘Y’ require constructors? If yes why.[PU:2013 spring]
16. What is containership? How does it differ from inheritance, describe how an object of a
class that contain object of another classes are created.[PU:2013 fall]
17. How composition differs from inheritance?
18. Explain how composition provide reusability?[PU:2018 fall]
19. Compare and contrast composition and inheritance?[PU:2015 fall]
Programming Questions:
1) WAP to enter information of n students and then display is using the concept multiple
inheritance,[PU: 2015 fall]
2) Write a complete program with reference to the given figure.
3) The following figure shows the minimum information required for each class. Write a
progam by realizing the necessary member functions to read and display information of
individual object. Every class should contain at least one constructor and should be
inherited from other classes as well.[PU:2019 fall]
5) The following figure shows minimum information required for each class.
i) Write a Program to realize the above program with necessary member functions to
create the database and retrieve individual information
7) The following figure shows the minimum information required for each class. Write a
program to realize the above program with necessary member functions to create the
database and retrieve individual information .Every class should contain at least one
constructor and should be inherited to other classes as well.[PU:2010 spring][PU 2009
fall]
i. Lecturer(subject,department)
Function Overloading
The method of using same function name but with different parameter list along with
different data type to perform the variety of different tasks is known as function
overloading.
The correct function is to be invoked is determined by checking the number and type of
arguments but not function return type.
#include<iostream>
using namespace std;
class calcarea
{
public:
int area(int);
int area(int,int);
float area(float);
};
int calcarea::area(int s)
{
return(s*s);
}
int calcarea::area(int l,int b)
{
return(l*b);
}
float calcarea::area(float r)
{
return(3.14*r*r);
}
int main()
{
calcarea c1,c2,c3;
cout<<"Area of square="<<c1.area(5)<<endl;
cout<<"Area of Rectangle="<<c2.area(5,10)<<endl;
cout<<"Area of Circle="<<c3.area(2.5f)<<endl;
return 0;}
Things to be understand
Usually Operations can perform only on basic data type. Example int a,b,c;
c=a+b; But if we declare a class complex {} and complex c1,c2,c3 ;
c3=c1+c2;is not possible because object is user defined data type.
Operator overloading helps to define usuage of operator for user defined data type i.e.
objects.
After overloading operands used with operator are objects instead of basic data types.
Note:
Operator function must be either member function (non-static) or friend function.
Friend function will have only one argument for unary operators and two for binary
operators.
Member function has no arguments for unary operators and only one for binary
operators.
This is because the object used to invoke the member function is passed implicitly and
therefore available for member function. This is not the case with friend functions.
Arguments may be passed either by value or by reference. Operator functions are declared in
class using prototype as follows.
vector operator+(vector); //vector addition
vector operator-(); //unary minus
friend vector operator+(vector,vector); //vector addition
friend vector operator-(vector); //unary minus
vector operator-(vector &a); //subtraction
int operator==(vector); //comparison
friend int operator==(vector,vector); //comparison
vector is a datatype of class and may represent both magnitude and direction (as in physics and
engineering) or a series of points called elements(as in mathematics).
Note:
Here op represents the operator being overloaded.
x and y represents the object.
#include<iostream>
using namespace std;
class space
{
private:
int x;
int y;
int z;
public:
void getdata(int a,int b,int c);
void display();
void operator -();
};
void space::getdata(int a,int b,int c)
{
x=a;
y=b;
z=c;
}
void space::display()
{
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
cout<<"z="<<z<<endl;
}
void space::operator -()
{
x=-x;
y=-y;
z=-z;
}
s:
x=5;
y=10;
z=15;
-s:
x=-5;
y=-10;
z=-15;
#include<iostream>
using namespace std;
class space
{
private:
int x;
int y;
int z;
public:
void getdata(int a,int b,int c);
void display();
friend space operator -(space s);
};
int main()
{
space s1,s2;
s1.getdata(5,10,15);
cout<<"s:"<<endl;
s1.display();
cout<<"-s:"<<endl;
s2=-s1;
s2.display();
return 0;
}
Output
Count=3
Count =4
Count =4
#include<iostream>
using namespace std;
class counter
{
private:
int count;
public:
void getdata (int x)
{
count=x;
}
void showdata( )
{
cout<<"count="<<count<<endl;
}
counter operator++(int);
};
counter counter::operator ++(int)
{
counter temp;
temp.count=count++;
return temp;
}
int main( )
{
counter c1,c2;
c1.getdata(5);
c1.showdata();
c2=c1++;
c1.showdata();
c2.showdata();
return 0;
}
Output:
count =5
count =6
count =5
#include<iostream>
using namespace std;
class counter
{
private:
int count;
public:
void getdata (int x)
{
count=x;
}
void showdata( )
{
cout<<"count="<<count<<endl;
}
void operator++(int);
};
void counter::operator ++(int)
{
count++;
}
int main( )
{
counter c1;
c1.getdata(5);
c1.showdata();
c1++;
c1.showdata();
return 0;
}
Output :
Count =5
Count=6
Count=6
#include<iostream>
using namespace std;
class fibo
{
private:
int a,b,c;
public:
fibo()
{
a=-1;
b=1;
c=a+b;
}
void display()
{
cout<<c<<",";
}
void operator++()
{
a=b;
b=c;
c=a+b;
}
};
int main()
{
int n,i;
fibo f;
cout<<"Enter the number of terms"<<endl;
cin>>n;
for(i=0;i<n;i++)
{
f.display();
++f;
}
return 0;
}
Overloading + operator
Write a program to add two complex number using binary operator overloading.
[PU:2013 fall]
#include<iostream>
using namespace std;
class complex
{
private:
int real,imag;
public:
complex()
{
}
complex(int r,int i)
{
real=r;
imag=i;
}
void display()
{
cout<<real<<"+i"<<imag<<endl;
}
complex operator +(complex);
};
complex complex::operator +(complex c2)
{
complex temp;
temp.real=real+c2.real;
temp.imag=imag+c2.imag;
return temp;
}
#include <iostream>
using namespace std;
class complex
{
private:
int real ;
int imag ;
public:
complex()
{
}
complex(int r, int i)
{
real=r;
imag=i;
}
void display()
{
cout<<real<< "+i"<<imag<<endl;
}
friend complex operator+ (complex,complex) ;
};
int main()
{
complex c1(5,3);
complex c2(3,4);
complex c3;
c3=c1+c2;
cout<<"c1=";
c1.display();
cout<<"c2=";
c2.display();
cout<<"c3=";
c3.display();
return 0;
}
#include<iostream>
using namespace std;
class Arithmetic
{
private:
float num;
public:
void getdata()
{
cout<<"Enter the number"<<endl;
cin>>num;
}
void putdata()
{
cout<<num<<endl;
}
Arithmetic operator+(Arithmetic);
Arithmetic operator*(Arithmetic);
Arithmetic operator-(Arithmetic);
Arithmetic operator/(Arithmetic);
};
Arithmetic Arithmetic::operator+(Arithmetic b)
{
Arithmetic temp;
temp.num=num+b.num;
return temp;
}
Arithmetic Arithmetic::operator*(Arithmetic b)
{
Arithmetic temp;
temp.num=num*b.num;
return temp;
}
Arithmetic Arithmetic::operator-(Arithmetic b)
{
Arithmetic temp;
temp.num=num-b.num;
return temp;
}
int main()
{
Arithmetic a,b,c;
a.getdata();
b.getdata();
c=a+b;
cout<<"Additon of two objects="<<endl;
c.putdata();
cout<<"Multiplication of two objects="<<endl;
c=a*b;
c.putdata();
cout<<"Substraction of two objects="<<endl;
c=a-b;
c.putdata();
cout<<"Division of two objects="<<endl;
c=a/b;
c.putdata();
return 0;
}
#include<iostream>
using namespace std;
class complex
{
private:
int real,imag;
public:
complex()
{
}
complex(int r,int i)
{
real=r;
imag=i;
}
void display()
{
cout<<real<<"+i"<<imag<<endl;
}
friend complex operator +(complex c1,complex c2);
friend complex operator -(complex c1,complex c2);
};
complex operator +(complex c1,complex c2)
{
complex temp;
temp.real=c1.real+c2.real;
temp.imag=c1.imag+c2.imag;
return temp;
}
complex operator -(complex c1,complex c2)
{
complex temp;
temp.real=c1.real-c2.real;
temp.imag=c1.imag-c2.imag;
return temp;
}
#include<iostream>
using namespace std;
#include <conio.h>
class Time
{
private:
int hrs,mins,secs;
public:
Time()
{
hrs=0, mins=0; secs=0;
}
Time(int h,int m,int s)
{
hrs=h;
mins=m;
secs=s;
}
void display()
{
cout<< hrs<< ":"<<mins<<":"<< secs<<endl;
}
Time operator+(Time);
};
int main()
{
Time t1(5,25,45);
Time t2(2,35,10);
Time t3;
t3 = t1 + t2;
cout<<"First time=";
t1.display();
cout << "Second time=";
t2.display();
cout << "Sum =";
t3.display();
return 0;
}
#include<iostream>
using namespace std;
#include <conio.h>
class Time
{
private:
int hrs,mins,secs;
public:
Time()
{
hrs=0, mins=0; secs=0;
}
Time(int h,int m,int s)
{
hrs=h;
mins=m;
secs=s;
}
void display()
{
cout<< hrs<< ":"<<mins<<":"<<secs<<endl;
}
friend Time operator+(Time,Time);
};
#include<iostream>
using namespace std;
class dist
{
private:
int feet;
int inch;
public:
dist()
{
feet=0;
inch=0;
}
dist(int f, float i)
{
feet=f;
inch=i;
}
void display()
{
cout<< feet <<"feet"<< inch<<"inch"<<endl;
}
void operator +=(dist d);
};
#include<iostream>
#include<string.h>
using namespace std;
class stringc
{
private:
char str[50];
public:
stringc()
{
}
stringc(char s[])
{
strcpy(str,s);
}
int main()
{
Time t1(3,15,45);
Time t2(4,15,45);
if(t1 == t2)
{
cout << "Both the time values are equal";
}
else
{
cout << "Both the time values are not equal";
}
return 0;
}
#include<iostream>
using namespace std;
class maximum
{
private:
int x;
public:
maximum(int a)
{
x=a;
}
Type conversion:
Type conversion is converting one type of data to another type.
Compiler automatically converts basic to another basic data type (for eg int to float,
float to int etc.) by applying type conversion rule provided by the compiler.
The type of data to the right of the assignment operator (=) is automatically converted
to the type of variable on the left.
For example:
The statements:
int m;
float x=3.14159
m=x;
Value stored in m is 3 because, here the fractional part is truncated.
Compiler does not support automatic type conversion for user defined data type. Therefore, we
must design conversion routines for the type conversion of user defined data type.
There are three possible type conversions are:
#include<iostream>
using namespace std;
class time
{
int hours;
int minutes;
public:
time(int t)
{
hours=t/60;
minutes=t%60;
}
void display()
{
cout<<"Hours="<<hours<<endl;
cout<<"Minutes="<<minutes<<endl;
}
};
int main()
{
int duration=65;
time t1=duration;
t1.display();
return 0;
}
After conversion, the hours members of t1 contains the value 1and minutes member contains
the value 5,denoting 1 hours and 5 minutes.
#include <iostream>
using namespace std;
class dist
{
private:
int feet;
float inches ;
public:
dist()
{
}
dist(float m)
{
float f=3.28083*m ;
feet=int(f) ;
inches=12*(f-feet) ;
}
void display()
{
cout<<feet<<"feet"<<inches<<"inches"<<endl;
}
};
int main()
{
float meter=12.5;
dist d1;
d1=meter;
d1.display();
}
Make a class called memory with member data to represent bytes, kilobytes, and megabytes.
in your program, you should be able to use statements like m1=1087665;
where m1 is an object of class memory and 1087665 is an integer representing some arbitrary
number of bytes. Your program should display memory in a standard format like: 1
megabytes 38 kilobytes 177 bytes.
#include<iostream>
using namespace std;
class item
{
private:
float price;
int quantity;
public:
item(float p,int q)
{
price=p;
quantity=q;
}
void display()
{
cout<<"Price of items="<<price<<endl;
cout<<"Quantity of items="<<quantity<<endl;
}
operator float()
{
return (price*quantity);
}
};
int main()
{
item i1(255.5,10);
float total;
i1.display();
total=i1;
cout<<"Total amount="<<total<<endl;
return 0;
}
void display()
{
cout<<feet<< "feet"<<inches<<"inches"<<endl;
}
operator float()
{
float f=inches/12 ;
f=f+feet ;
return(f/3.28083);
}
};
int main( )
{
dist d1(5,3.6) ;
float m=d1;
cout<<"Distance in feet and inches:"<<endl;
d1.display();
cout<<"Distance in meter="<<m<<endl;
return 0;
}
Define type conversion. Explain with conversion from one class type to another class type.
[PU: 2016 fall]
Such conversions between objects of different classes can be carried out by either a constructor
or a conversion function.
Note:
Conversion form a class to any other type (or any other class) should make use of
casting operator function in the source class.
On the other hand to perform the conversion from any other type /class type
constructor should be used in destination class.
#include<iostream>
#include<math.h>
using namespace std;
class Rectangle
{
private:
float xco;
float yco;
public:
Rectangle()
{
xco=0.0;
yco=0.0;
}
Rectangle(float x,float y)
{
xco=x;
yco=y;
}
void display()
{
cout<<"("<<xco<<","<<yco<<")"<<endl;
}
};
class Polar
{
private:
float radius;
float angle;
public:
Polar()
{
radius=0.0;
angle=0.0;
}
#include<iostream>
#include<math.h>
using namespace std;
class Polar
{
private:
float radius;
float angle;
public:
Polar()
{
radius=0.0;
angle=0.0;
}
class Rectangle
{
private:
float xco;
float yco;
public:
Rectangle()
{
xco=0.0;
yco=0.0;
}
Rectangle(float x,float y)
{
xco=x;
yco=y;
}
void display()
{
cout<<"("<<xco<<","<<yco<<")"<<endl;
}
operator Polar()
{
float a=atan(yco/xco);
float r=sqrt(xco*xco+yco*yco);
return Polar(r,a);
}
};
#include <iostream>
#include <math.h>
using namespace std;
class Polar
{
private:
float radius;
float angle;
public:
Polar()
{
radius=0.0;
angle=0.0;
}
Polar(float r, float a)
{
radius=r;
angle=a;
}
void display()
{
cout<<"("<<radius<<","<<angle<<")"<<endl;
}
float getr()
{
return radius;
}
class Rectangle
{
private:
float xco;
float yco;
public:
Rectangle()
{
xco=0.0;
yco=0.0;
}
void display()
{
cout<<"("<<xco<<","<<yco<<")";
}
Rectangle(Polar p)
{
float r=p.getr();
float a=p.geta();
xco=r*cos(a);
yco=r*sin(a);
}
};
int main()
{
Polar p(10.0,0.785398);
Rectangle r;
r=p;
cout<<"Polar coordinates=";
p.display();
cout<<"Rectungular coordinates=:";
r.display();
return 0;
}
#include<iostream>
#include<math.h>
using namespace std;
class Rectangle
{
private:
float xco;
float yco;
public:
Rectangle()
{
xco=0.0;
yco=0.0;
}
Rectangle(float x,float y)
{
xco=x;
yco=y;
}
void display()
{
cout<<"("<<xco<<","<<yco<<")"<<endl;
}
float getx()
{
return xco;
}
float gety()
{
return yco;
}
};
Polar(Rectangle r)
{
float x=r.getx();
float y=r.gety();
angle=atan(y/x);
radius=sqrt(x*x+y*y);
}
};
int main()
{
Rectangle r(7.07107,7.07107);
Polar p;
p=r;
cout<<"Rectangular coordinates=";
r.display();
cout<<"Polar coordinates=";
p.display();
return 0;
}
Note: When accessing members of class using object pointer the arrow operator (->)
is used instead to dot operator.
Example:
#include<iostream>
using namespace std;
class student
{
private:
char name[20];
int roll;
public:
void getdata()
{
cout<<"Enter student Name"<<endl;
cin>>name;
cout<<"Enter student Rollno"<<endl;
cin>>roll;
}
int main()
{
student st;
student *ptr;
ptr=&st;
ptr->getdata();
ptr->display();
return 0;
}
#include<iostream>
using namespace std;
class item
{
private:
int code;
float price;
int main()
{
int n,i,x;
float y;
cout<<"Enter the number of item"<<endl;
cin>>n;
item *ptr=new item[n];
item *d=ptr; //&ptr[0]
for(i=0;i<n;i++)
{
cout<<"Input code and price of item"<<endl;
cin>>x>>y;
ptr->getdata(x,y);
ptr++;
}
for(i=0;i<n;i++)
{
cout<<"Item:"<<i+1<<endl;
d->display();
d++;
}
return 0;
}
Can you derive a pointer from a base class? Explain with suitable example
Yes, we can derive a pointer from a base class. Pointers to object of base class are type
compactible with pointer to objects of the derived class. Therefore, a single pointer variable can
be made to point to objects belonging to different classes. For example, if B is a base class and
D is the derived class from B, then a pointer declared as a pointer to B can also be a pointer to
D. consider the following declarations.
B *bptr; //pointer to class B type variable
B b; //base object
D d; //derived object
bptr=&b; //bptr points to object b
This is perfectly valid with C++ because d is an object derived from the class B.
Although C++ permits a base pointer to point to any object derived from that base, the pointer
cannot be directly used to access all the members of the derived class. we can access only those
members which are inherited from B and not the members that originally belong to D. We may
have to use another pointer declared as pointer to derived type.
Program:
#include<iostream>
using namespace std;
class B
{
public:
int x;
void display()
{
cout<<"x="<<x<<endl;
}
};
int main ()
{
B b1;
B *bptr; //base pointer
bptr=&b1; //base address
bptr->x = 10; //access B via base pointer
cout<<"bptr points to base object"<<endl;
bptr->display();
D d1;
bptr=&d1; //address of derived object
bptr->x=10; //access D via base pointer
//bptr->y = 20; wont work
cout<<"bptr now points to derived object"<<endl;
bptr->display(); //access to base class function
cout<<"using ((D*)bptr)"<<endl;
((D*)bptr)->y=30;
((D*)bptr)->display();
return 0;
}
The statements,
dptr->display();
((D*)bptr)->display(); //cast bptr to D type
Displays the contents of derived object.
int main()
{
B b1;
B *bptr; //base pointer
bptr=&b1; //base address
cout<<"bptr points to base object"<<endl;
bptr->display();
D d1;
bptr=&d1; //address of derived object
cout<<"bptr now points to derived object"<<endl;
bptr->display(); //access to base class member
D *dptr;
dptr=&d1;
cout<<"dptr is a derived type pointer"<<endl;
dptr->display();
Example:
#include<iostream>
using namespace std;
class Employee
{
private:
int eid;
float salary;
public:
Employee(int eid,float salary)
{
this->eid=eid;
this->salary=salary;
}
void display()
{
cout<<"Employee ID="<<eid<<endl;
cout<<"Salary="<<salary<<endl;
}
};
Example:
#include<iostream>
#include<string.h>
using namespace std;
class person
{
char name[20];
float age;
public:
person()
{
}
person (char n[],float a)
{
strcpy(name,n);
age=a;
}
person greater(person x)
{
if(x.age>=age)
{
return x;
}
else
{
return *this;
}
}
int main()
{
person p1("Ram",52);
person p2("Hari",24);
person p3;
p3=p1.greater(p2);
cout<<"Elder person is:"<<endl;
p3.display();
return 0;
}
Things to be understand:
In addition to the explicit parameters in their argument lists, every class member function
(method) receives an additional hidden parameter, the "this" pointer. The "this" pointer
addresses the object on which the method was called. Thus, this pointer is used as a pointer to
the class object instance by the member function.
Each object maintains its own set of data members, but all objects of a class share a single set of
methods. This is, a single copy of each method exists within the machine code that is the output
of compilation and linking. A natural question is then if only a single copy of each method exists,
and its used by multiple objects, how are the proper data members accessed and updated. The
compiler uses the "this" pointer to internally reference the data members of a particular object.
The member functions of every object have access to a pointer named this, which points to the
object itself. When we call a member function, it comes into existence with the value of this set
to the address of the object for which it was called. The this pointer can be treated like any other
pointer to an object
#include<iostream>
using namespace std;
class B
{
public:
virtual void show()
{
cout<<"Show base"<<endl;
}
};
class D:public B
{
public:
void show()
{
cout<<"Show derived"<<endl;
}
};
1. What is virtual function? When and how to we make function virtual? Explain with
suitable example. PU:2010 spring]
A virtual function is a member function declared in base class with keyword virtual and uses a
single pointer to base class pointer to refer to object of different classes.
When we use the same function name in both base and derived classes, the function in base
class is declared as virtual using the keyword virtual preceding its normal declaration. When a
function is made virtual, C++ determines which function is use at runtime based on the type of
object pointed to by the base pointer, rather than the type of the pointer. Thus by making the
base pointer to point object of different versions of the virtual functions.
int main()
{
B b1;
D d1;
B *bptr;
cout<<"bptr points to base"<<endl;
bptr=&b1;
bptr->show(); //calls base class function
cout<<"bptr points to derived"<<endl;
bptr=&d1;
bptr->show(); //calls derived class function
return 0;
}
Note:
This is because compiler actually ignores the content of the pointer bptr and chooses a
member function that matches the type of the pointer.
whereas the statement
bptr->show();
calls the derived version of show().This is because function show() has been made virtual in
Base class.
This is because first the base pointer has address of the base class object, then its content is
changed to contain the address of the derived object.
3. How can you achieve runtime polymorphism in C++? Discuss with suitable example.
We should use virtual functions and pointers to objects to achieve run time
polymorphism. For this, we use functions having same name, same number of
parameters, and similar type of parameters in both base and derived classes. The
function in the base class is declared as virtual using the keyword virtual.
A virtual function uses a single pointer to base class pointer to refer to all the derived objects.
When a function in the base class is made virtual, C++ determines which function to use at run
time based on the type of object pointed by the base class pointer, rather than the type
of the pointer
A bookshop sells both books and video tapes. Create an abstract class known as media that
stores the title and price of a publication. Create two child classes one for storing the number
of pages in a book and another for storing the playing time of a tape. A function display is
used in all the classes to display the class contents. Create necessary constructors in the child
classes to store the information. In the main display the information regarding the book and
tape using the base pointer (an object pointer of the class media)
Abstract class
A class having at least one pure virtual function is called an abstract class.
The object of abstract classes cannot be created.
Pointers to abstract class can be created for selecting the proper virtual function.
An abstract class is designed to act only as base class .It is a design concept in program
development and provides a base upon which program is built.
Sometimes implementation of all function cannot be provided in a base class because
we don’t know the implementation. For example, let Shape be a base class. We cannot
provide implementation of function draw() in Shape, but we know every derived class
must have implementation of draw().In this case concept of abstract class is used.
Inheritance should be there. Function overriding cannot be done within a class. For this
we require a derived class and a base class.
Function that is redefined must have exactly the same declaration in both base and
derived class, that means same name, same return type and same parameter list.
#include<iostream>
using namespace std;
class A
{
public:
void display()
{
cout<<"This is Base class"<<endl;
}
};
class B : public A
{
public:
void display()
{
cout<<"This is Derived class"<<endl;
}
};
int main()
{
B b;
b.display();
return 0;
}
Here, the function display() is overridden.
If the function is invoked from an object of the derived class, then the function in
the derived is executed.
If the function is invoked from an object of the base class, then the base class
member function is invoked.
To create an object of the constructor of the object class must be of the same type as
class. But it is not possible with virtually implemented constructor.
At the time of calling constructor, the virtual table would not have been to create any
function calls.
Whereas destructor can be virtual.
Let’s first see what happens when we do not have a virtual Base class destructor.
class Base
{
public:
~Base()
{
cout << "Base class destructor"<<endl;
}
};
int main()
{
Base* ptr = new Derived; //Base class pointer points to derived class object
delete ptr;
}
Output:
Base class Destructor
In the above example, delete ptr will only call the Base class destructor, which is undesirable
because, then the object of Derived class remains un-destructed, because its destructor is
never called. Which leads to memory leak situation.
Output:.
Derived class Destructor
Base class Destructor
When we have Virtual destructor inside the base class, then first Derived class's destructor is
called and then Base class's destructor is called, which is the desired behavior.
5. Design a soccer player class that includes three ineger fields:a player’s jersey
number,number of goals,number of assists and necessary constructors to initialize the
data members.Overload the > operator (Greater than) .One player is considered greater
than another if the sum of goals plus assists is greater than that of others.Create an
array of 11 soccer players,then use the overloaded > operator to find the greater total
of goal plus assists.[PU:2015 fall]
6. Write a simple program to overload unary ++ operator.[PU: 2016 spring]
7. Make a class called memory with member data to represent bytes, kilobytes and
megabytes.Read the value of memory in bytes from the user as basic types and display
the result in user defined memory type. Like for m (basic type) = 108766, your program
should display as: 1 megabyte 38 kilobytes 177 bytes. [Hint: Use basic to user defined
data conversion method.
8. Write a program that converts object that represents 24 hrs times to 12 hrs times and
vice versa.
9. Write a program to create a class age with attributes YY, MM, DD and convert the object
of class age to basic data type int days.
10. Write a program finding area of square ,rectangle, triangle. Use function overloading
technique.
11. Write a program to implement vector addition using operator overloading
i. Using Friend Function
ii. Without using Friend Function(using member function)
CLASS TEMPLATE
We can create class templates for generic class operations. Sometimes, we need a class
implementation that is same for all classes, only the data types used are different. Normally, we
would need to create a different class for each data type or create different member variables
and functions within a single class. This promotes the coding redundancy and will be hard to
maintain, as a change is one class/function should be performed on all classes/functions.
However, class templates make it easy to reuse the same code for all data types.
Example:
For integer data example <int> e1; Here e1 is object of class example
For float data example <float> e2; Here e2is object of class example
For char data example <char> e3; Here e3 is object of class example
#include<iostream>
using namespace std;
template<class T>
class sample
{
private:
T a,b,s;
public:
void setdata(T x,T y)
{
a=x;
b=y;
}
void add()
{
s=a+b;
cout<<s<<endl;
}
};
#include<iostream>
using namespace std;
template<class T>
class compare
{
private:
T a,b;
public:
compare(T x,T y)
{
a=x;
b=y;
}
T max()
{
return (a>b)?a:b;
}
};
int main()
{
compare <int> c1(5,6);
compare <float> c2(4.9,32.4);
cout<<"Maximum value among two integer ="<<c1.max()<<endl;
cout<<"Maximum value among two float ="<<c2.max()<<endl;
return 0;
}
public:
stack()
{
top = -1;
}
void push(T data)
{
if (top == (max -1))
cout << "stack is full"<<endl;
else
{
top++;
stk[top]= data;
}
}
void pop()
{
if (top == -1)
cout << "stack is empty"<<endl;
else
{
top--;
}
}
void show()
{
for(int i=top;i>=0;i--)
cout << "stack["<< i <<"]" <<stk[i]<<endl;
}
};
template<class template_type>
return_type class_name <template_type>::function_name(template_type arg)
{
//body of function template
}
Function template can be used to create a family of functions with different argument
types.
A single function template can work with different data types.
Any type of function argument is accepted by the function.
#include<iostream>
using namespace std;
template<class T>
void calculate(T a,T b)
{
T avg,pro;
avg=(a+b)/2;
pro=a*b;
cout<<"Average="<<avg<<endl;
cout<<"Product="<<pro<<endl;
}
#include<iostream>
using namespace std;
template <class T>
void sum(T x,T y)
{
T s;
s=x+y;
cout<<"s="<<sum<<endl;
}
int main()
{
int i1,i2;
float f1,f2;
cout<<"Enter two Integer"<<endl;
cin>>i1>>i2;
sum(i1,i2);
cout<<"Enter two Float"<<endl;
cin>>f1>>f2;
sum(f1,f2);
return 0;
}
6. Write a program to find the sum of integer and float array using function templates.
#include<iostream>
using namespace std;
template<class T>
T sum(T a[],int size)
{
T s=0;
for(int i=0;i<size;i++)
{
s=s+a[i];
}
return s;
}
Write a program to find the minimum elements in an array using function template.
#include<iostream>
using namespace std;
template<class T>
T find_min(T arr[],int n)
{
T min=arr[0];
for(int i=0;i<n;i++)
{
if(arr[i]<min)
{
min=arr[i];
}
}
return min;
}
Write a program to find the maximum elements in an array using function template.
#include<iostream>
using namespace std;
template<class T>
T find_max(T arr[],int n)
{
T max=arr[0];
for(int i=0;i<n;i++)
{
if(arr[i]>max)
{
max=arr[i];
}
}
return max;
int main()
{
int imax;
float fmax;;
int x[6]={50,10,30,20,40,70};
float y[5]={1.1,5.5,3.3,4.4,2.2};
imax=find_max(x,6);
fmax=find_max(y,5);
cout<<"Maximum value in integer array="<<imax<<endl;
cout<<"Maximum value in float array="<<fmax<<endl;
return 0;
}
We can use more than one generic data type in template statement using a comma separated
list as shown below.
#include<iostream>
using namespace std;
template <class T1,class T2>
void display(T1 x,T2 y)
{
cout<<x<<" "<<y<<endl;
}
int main()
{
cout<<"calling function template with integer and string type parameters"<<endl;
display(199,"pokhara");
cout<<"calling function template with float and integer type parameters"<<endl;
display(12.34,5);
return 0;
}
Write a program to add two integers; two floats and one integer and one float numbers
respectively. Display the final result in the float.[PU:2005 fall]
#include<iostream>
using namespace std;
template <class T1,class T2>
float sum(T1 x,T2 y)
{
return(x+y);
}
A template function may be overloaded either by template functions or ordinary functions of its
name. In such cases, the overloading resolution is accomplished as follows.
An error is generated if no match is found. Note that no automatic conversions are applied to
arguments on the template functions. Program below shows how a template function is
overloaded with explicit function.
#include<iostream>
#include<string.h>
using namespace std;
template <class T>
void display(T x)
{
cout<<"Overloaded Template Display1:"<<x<<endl;
}
int main()
{
display(100);
display(12.34);
display(100,15.4);
display('C’);
return 0;
}
Output:
Explicit display:100
Overloaded Template Display1:12.34
Overloaded Template Display2:100,12.34
Overloaded Template Display1:C
C++ templates enable us to define a family of functions or classes that can operate on
different types of information.
We can use templates in situations that result in duplication of the same code for
multiple types. For example, we can use function templates to create a set of functions
that apply the same algorithm to different data types.
Deliver fast, efficient, and robust code
Easy to use
When we use templates in combination with STL – it can drastically reduce development
time.
Demerit
Historically, some compilers exhibited poor support for templates. So, the use of
templates could decrease code portability.
Automatically generated source code can become overwhelmingly huge.
Compile-time processing of templates can be extremely time consuming.
It can be difficult to debug code that is developed using templates. Since the compiler
replaces the templates, it becomes difficult for the debugger to locate the code at
runtime.
Templates are in the headers, which require a complete rebuild of all project pieces
when changes are made.
Many compilers lack clear instructions when they detect a template definition error.
This can increase the effort of developing templates, and has prompted the
development of Concepts for possible inclusion in a future C++ standard.
No information hiding. All code is exposed in the header file. No one library can solely
contain the code .
Though STL itself is a collection of template classes, templates are not used to write
conventional libraries.
Types of Exceptions
The exception handling mechanism suggests a separate error handling code that
performs the following tasks.
1. Find the problem (Hit the exception)
2. Inform the error has occurred (Throw the exception)
3. Receive the error information (Catch the exception)
4. Take the corrective action (Handle the exception)
The error handling code mainly consists of two segments, one to detect error and throw
exceptions and other to catch the exceptions and to take appropriate actions.
C++ exception handling mechanism is basically built upon three keywords namely try, throw
and catch.
1. The keyword try is used to preface a block of statements (surrounded by braces) which
may generate exception. This block of statement is known as try block.
2. When as exception is detected, it is thrown using a throw statement in the try block.
3. A catch block defined by the keyword catch, catches the exception thrown by the throw
statement in the try block and handles it appropriately.
throw exception;
}
catch(type arg ) //catch the exception
{
// Block of statements that handles the exceptions
}
When the try block throws an exception, the program control leaves the try block and enters
the catch statement of the catch block. If the type of object thrown matches the arg type in the
catch statement, then the catch block is executed for handling the exception. If they do not
match, the program is aborted with the help of abort() function which is executed implicitly by
#include<iostream>
using namespace std;
int main()
{
int a,b,x;
cout<<"Enter values of a and b"<<endl;
cin >> a>>b;
x=a-b;
try
{
if(x!=0)
{
cout << "Result (a/x)="<< a/x <<endl;
}
else
{
throw(x); //throws an object
}
}
catch(int i) //catches an exception
{
cout<< "Exception caught:DIVIDE BY ZERO"<<endl;
}
cout << "END";
return 0;
}
Output:
First Run:
Second Run:
It is possible that a program segment has more than one condition to throw an exception.
In such cases ,we can associate more than one catch statement with a try (much like conditions
in switch statement) as shown below.
try
{
//try block
}
catch(type1 arg)
{
//Catch block1
}
catch(type2 arg)
{
//catch block2
}
. . . . .. . . . . . . .
catch(typeN arg)
{
Catch block N
}
When an exception is thrown, the exception handlers are searched in order for an appropriate
match. The first handler that yields a match is executed. After executing the handler, the
control goes to the first statement after the last catch block for that try. When no match is
found, the program is terminated.
It is possible that arguments of several catch statements match the type of an exception. In
such cases the first handler that matches the exception type is executed.
Example of program where multiple catch statements are used to handle various types of
exceptions.
x==0
Caught a character
End of try-catch system
x==-1
Caught a double
End of try-catch system
x==2
End of try-block
End of try-catch system
Note:
Catch block must be immediately after try block without any code between them.
#include<iostream>
using namespace std;
void divide(int x,int y,int z)
{
cout<<"We are inside the function"<<endl;
if((x-y)!=0)
{
int r=z/(x-y);
cout<<"Result="<<r<<endl;
}
else
{
throw(x-y);// throw point;
}
}
int main()
{
try
{
cout<<"We are inside the try block"<<endl;
divide(10,20,30);
divide(10,10,20);
}
catch(int i)
{
cout<<"caught an exception"<<endl;
}
return 0;
}
Output:
#include<iostream>
using namespace std;
void divide(double x,double y)
{
cout<<"Inside function"<<endl;
try
{
if(y==0)
throw y;
else
cout<<"Division="<<x/y<<endl;
}
catch(double)
{
cout<<"caught double inside function"<<endl;
throw;
}
cout<<"End of function"<<endl;
}
int main()
{
cout<<"Inside main" <<endl;
try
{
divide(10.5,2.0);
divide(20.0,0.0);
}
catch(double)
{
cout<<"caught double inside main"<<endl;
}
cout<<"End of main"<<endl;
return 0;
}
Inside main
Inside function
Division=5.25
End of function
Inside function
Caught double inside function
Caught double inside main
End of main
When an exception is rethrown, it will not be caught by the same catch statement or any other
catch in that group. Rather, it will be caught by an appropriate catch in the outer try/catch
sequence only.
A catch handler itself may detect and throw an exception. Here again, the exception thrown will
not be caught by any catch statements in that group. It will be passed on to the next outer
try/catch sequence for processing.
These three components work in conjunction with one another to provide support to a
variety of programming solutions. The relationship between the three components is as
shown in figure below. Algorithms employ iterators to perform operation stored in
containers.
Features of STL
It helps in saving time, efforts, load fast, high quality programming because STL provides
well written and tested components, which can be reuse in our program to make our
program more robust.
1. Sequence containers
Vector
List
Deque
2. Associative containers
Associative containers are designed to support direct access to element using keys. They are
not sequential. There are four types of associative containers.
Set
Multiset
Map
Multimap
All these containers store data in a structure called tree which facilitates fast searching,deletion
and insertion. However these are very slow for random access and inefficient for sorting.
3. Derived containers
The STL provides three derived containers namely stack, queue, and priority queue. These are
also called containers adaptors.
Stack Queues and priority queues can be created from different sequence containers. The
derived containers do not support iterators and therefore we cannot use them for data
manipulation. However, they support two member functions pop() and push() for
implementing deleting and inserting operations.
When we make an object (be it a child or a software system) responsible for specific
actions, we expect a certain behavior, at least when the rules are observed.
Responsibility implies a degree of independence or noninterference.
If we tell a child that she is responsible for cleaning her room, we do not normally stand
over her and watch while that task is being performed-that is not the nature of
responsibility. Instead, we expect that, having issued a directive in the correct fashion,
the desired outcome will be produced.
In case of, conventional programming we tend to actively supervise the child while she’s
performing a task.
In case of OOP we tend to handover to the child responsibility for that performance
Conventional programming proceeds largely by doing something to something else-
modifying a record or updating an array. Thus, one portion of code in a software system
is often intimately tied by control and data connections to many other sections of the
system. Such dependencies can come about through the use of global variables, through
use of pointer values or simply through inappropriate use of and dependence on
implementation details of other portions of code.
A responsibility-driven design attempts to cut these links, or at least make them as
unobtrusive as possible.
One of the major benefits of object-oriented programming occurs when software
subsystems are reused from one project to the next. For example, a simulation manager
might work for both a simulation of balls on a billiards table and a simulation of fish in a fish
tank. This ability to reuse code implies that the software can have almost no domain-
specific components; it must totally delegate responsibility for domain-specific behavior to
application-specific portions of the system. The ability to create such reusable code is not
one that is easily learned-it requires experience, careful examination of case studies
(paradigms, in the original sense of the word), and use of a programming language in which
such delegation is natural and easy to express.
The difference between the development of individual projects and of more sizable software
systems is often described as programming in the small versus programming in the large.
Programming in the small characterizes projects with the following attributes:
The software system is developed by a large team, often consisting of people with many
different skills. There may be graphic artists, design experts, as well as programmers.
Individuals involved in the specification or design of the system may differ from those
involved in the coding of individual components, who may differ as well from those
involved in the integration of various components in the final product. No single individual
can be considered responsible for the entire project, or even necessarily understands all
aspects of the project.
The major problem in the software development process is the management of details
and the communication of information between diverse portions of the project.
RDD focuses on what action must get accomplished and which object will accomplish
them.
The RDD approach focuses on modeling object behavior and identifying patterns of
communication between objects.
One objective of object oriented design is first to establish who is responsible for each
action to be performed.
The design process consists of finding key objects during their role and responsibilities
and understanding their pattern of communication.
RDD initially focuses on what should be accomplished not how. RDD tries to avoid
dealing with details.
If any particular action is to happen, someone must be responsible for doing it. No
action takes place without an agent.
One of the technique is use of index cards to represent individual class. such cards are
known as index cards.
Brief Description
The Interactive Intelligent Kitchen Helper (IIKH) is a PC-based application that will replace the
index-card system of recipes found in the average kitchen. But more than simply maintaining a
database of recipes, the kitchen helper assists in the planning of meals for an extended period,
say a week. The user of the IIKH can sit down at a terminal, browse the database of recipes, and
interactively create a series of menus. The IIKH will automatically scale the recipes to any
number of servings and will print out menus for the entire week, for a particular day, or for a
particular meal. And it will print an integrated grocery list of all the items needed for the recipes
for the entire period.
Initial specifications are almost always ambiguous and unclear on anything except the most
general points. So, the first task is to refine the specification.
The specifications for the final application will may change during the creation of the software
system, so it is important that, the design be developed to easily accommodate change and
that potential changes be noted as early as possible.
Equally important, at this point very high level decisions can be made concerning the structure
of the eventual software system. In particular, the activities to be performed can be mapped
onto components.
In order to uncover the fundamental behavior of the system, the design team first creates a
number of scenarios. That is, the team acts out the running of the application just as if it
already possessed a working system. An example scenario is as below.
Class Name
Responsibilities Collaborators
A class represents a collection of similar objects, a responsibility is something that a class knows
or does, and a collaborator is another class that a class interacts with to fulfill its
responsibilities.
Let us illustrate these concept with an example of Student CRC card
Student
Name Student
Seminar number Professor
Fees
Add Student
Drop student
Instructor
Professor
Name Seminar
Address
Email address
Salary
Provides information
Instructing seminar
Transcript
While working through scenarios, it is useful to assign CRC cards to different members of the
design team. The member holding the card representing a component records the
responsibilities of the associated software component, and acts as the “surrogate" for the
software during the scenario simulation. He or she describes the activities of the software
system, passing “control" to another member when the software system requires the
services of another component.
The physical separation of the cards encourages an intuitive understanding of the importance
of the logical separation of the various components, helping to emphasize the cohesion and
coupling (which we will describe shortly).
7.5.2 What/Who Cycle
First, the design team identifies what activity needs to be performed next.
This is immediately followed by answering the question of who performs the action.
In this manner, designing a software system is much like organizing a
collection of people, such as a club. Any activity that is to be performed must be assigned as a
responsibility to some component.
The secret to good object-oriented design is to first establish an agent for each action.
The design documentation records the major decisions made during software design, and
should thus be produced when these decisions are fresh in the minds of the creators.
Gives the initial picture of the larger structure hence should be carried out early in the
.development cycle.
CRC cards are one aspect of the design documentation, but many other important
decisions are not reflected in them. Arguments for and against any major design
alternatives should be recorded, as well as factors that influenced the final decisions.
Used for describing their dynamic interactions during the execution of a scenario.
In the diagram, time moves forward from the top to the bottom.
Each component is represented by a labeled vertical line.
A component sending a message to another component is represented by a horizontal
arrow from one line to another.
Similarly, a component returning control and perhaps a result value back to the caller is
represented by an arrow.
The commentary on the right side of the figure explains more fully the interaction taking
place.
With a time axis, the interaction diagram is able to describe better the sequencing of
events during a scenario. For this reason, interaction diagrams can be a useful
documentation tool for complex software systems.
Note:
Some authors use two different arrow forms, such as a solid line to represent message passing
and a dashed line to represent returning control.
Sequence diagram is a sub-category of Interaction diagram
The behavior of a component is the set of actions it can perform. The complete
description of all the behavior for a component is sometimes called the
protocol. For the Recipe component this includes activities such as editing the
preparation instructions, displaying the recipe on a terminal screen, or printing
a copy of the recipe.
The state of a component represents all the information held within it at a
given point of time. For our Recipe component the state includes the
ingredients and preparation instructions. Notice that the state is not static and
can change over time. For example, by editing a recipe (a behavior) the user
can make changes to the preparation instructions (part of the state).
2) Instances and classes
In the real application there will probably be many different recipes. However, all of these
recipes will perform in the same manner i.e. the behavior of each recipe is the same.
But the state (individual list of ingredients and instructions for preparation) differs
between individual recipes.
The term class is used to describe a set of objects with similar behavior.
An individual representative of a class is known as an instance.
Note that behavior is associated with a class, not with an individual. That is, all instances
of a class will respond to the same instructions and perform in a similar manner.
On the other hand, state is a property of an individual. We see this in the various instances
of the class Recipe. We see this in the various instances of the class Recipe .They can all
perform the same actions (editing, displaying, printing) but use different data values.
The developer of a software component must provide the intended user with all the
information needed to make effective use of the services provided by the component,
and should provide no other information.
The developer of a software component must be provided with all the information
necessary to carry out the given responsibilities assigned to the component, and should
be provided with no other information.
Use pronounceable names. As a rule of thumb, if you cannot read a name out loud,
it is not a good one.
Use capitalization (or underscores) to mark the beginning of a new word within a
name, such as “CardReader" or “Card_reader," rather than the less readable
“cardreader."
Abbreviations should not be confusing. Is a “TermProcess" a terminal process,
something that terminates processes, or a process associated with a termi- nal?
Avoid names with several interpretations. Does the empty function tell whether
something is empty, or empty the values from the object?
Avoid digits within a name. They are easy to misread as letters (0 as O, 1 as l, 2 as
Z, 5 as S).
Name functions and variables that yield Boolean values so they describe clearly
the interpretation of a true or false value. For example, “Printer-IsReady" clearly
indicates that a true value means the printer is working, whereas “PrinterStatus"
is much less precise
Names for operations that are costly and infrequently used should be carefully
chosen as this can avoid errors caused by using the wrong function.
Once names have been developed for each activity, the CRC cards for each component are
redrawn, with the name and formal arguments of the function used to elicit each behavior
identified. An example of a CRC card for the Date is shown in Figure .
At this point, the design team can be divided into groups, each responsible for one or more
software components. The task now is to transform the description of a component into a
software system implementation. The major portion of this process is designing the data
structures that will be used by each subsystem to maintain the state information required to
fulfill the assigned responsibilities.
Once data structures have been chosen, the code used by a component in the fulfillment of a
responsibility is often almost self-evident. A wrong choice can result in complex and inefficient
programs.
It is also at this point that descriptions of behavior must be transformed into algorithms. These
descriptions should then be matched against the expectations of each component listed as a
collaborator, to ensure that expectations are fulfilled and necessary data items are available to
carry out each process.
If the previous steps were correctly addressed, each responsibility or behavior will be
characterized by a short description. The task at this step is to implement the desired
activities in a computer language.
As one programmer will not work on all aspects of a system, programmer will need to
master are understanding how one section of code fits into a larger framework and
working well with other members of a team.
There might be components that work in back ground (facilitators) that needs to be taken
into account.
An important part of analysis and coding at this point is:
i. Characterizing and documenting the necessary preconditions a software
component requires to complete a task.
ii. Verifying that the software component will perform correctly when presented
with legal input values.
Once software subsystems have been individually designed and tested, they can be
integrated into the final product. This is often not a single step, but part of a larger
process. Starting from a simple base, elements are slowly added to the system and tested,
using stubs-simple dummy routines with no behavior or with very limited behavior-for
the as yet unimplemented parts.
Testing of an individual component is often referred to as unit testing.
Next, one or the other of the stubs can be replaced by more complete code. Further
testing can be performed until it appears that the system is working as desired. (This is
sometimes referred to as integration testing. The application is finally complete when all
stubs have been replaced with working components.
Testing during integration can involve the discovery of errors, which then results in
changes to some of the components. Following these changes the components should be
once again tested in isolation before an attempt to reintegrate the software, once more,
into the larger system.
Re-executing previously developed test cases following a change to a software
component is sometimes referred to as regression testing.
The term software maintenance describes activities subsequent to the delivery of the initial
working version of a software system. A wide variety of activities fall into this category.
Errors, or bugs, can be discovered in the delivered product. These must be corrected,
either in updates or corrections to existing releases or in subsequent releases.
Requirements may change, perhaps as a result of government regulations or
standardization among similar products.
Hardware may change. For example, the system may be moved to different platforms, or
input devices, such as a pen-based system or a pressure-sensitive touch screen, may
become available. Output technology may change-for example, from a text-based system
to a graphical window-based arrangement.
User expectations may change. Users may expect greater functionality, lower cost, and
easier use. This can occur as a result of competition with similar products. Better
documentation may be requested by users.
A good design recognizes the inevitability of changes and plans an accommodation for them
from the very beginning.
Robot
Senses the path Sensor
Follows the sensors Robotic_Wheels
Steer itself forward
Sensors
Robotic_Wheels
An entity that has state and behavior is known as an object .If we consider the real-world, we
can find many objects around us, cars, dogs, humans, etc. All these objects have a state and a
behavior .If we consider a dog, then its state is - name, breed, color, and the behavior is -
barking, wagging the tail, running.
In object oriented programming problem is analyzed in terms of object and nature of
communication between them. Program object should be chosen such that they match closely
with real-world objects. In object oriented programming object's state is stored as data
member and behavior is defined using functions (methods).
When a program is executed, the object interact by sending message to one another. For
example, if “Customer” and “account” are two objects in a program then the customer object
may send a message to the account object requesting for the bank balance. Each object
contains data, and code (methods) to manipulate data. Objects can interact without having to
know details of each other’s data or code. It is sufficient to know the type of message accepted,
and the type of response returned by objects.
So, from above discussion we can say that “Everything is an object” in an object oriented
Programming.
2. With the help of object oriented programming, explain how can object oriented
programming cope in solving complex problem. [PU:2014 spring][PU:2018 fall]
When the software sizes grows large, due to the interconnections of software
components the complexity of software system increases. The interconnections of
software components means the dependence of one portion of code on another
portion. Due to complexity, it is difficult to understand program in isolation as well it
makes difficult to divide a task between a several programs.
The abstraction mechanism is used to manage complexity. The Abstraction is
mechanism displays only essential information and hiding the details.
Abstraction is often combined with a division into components. For example, we divided
the automobile into the engine and the transmission. Components are carefully chosen
so that they can encapsulate certain key features and interact with another component
through simple and fixed interface.
Abstraction means displaying only essential information and hiding the details. Data abstraction
refers to providing only essential information about the data to the outside world, hiding the
background details or implementation.
Consider a real life example of a man driving a car. The man only knows that pressing the
accelerators will increase the speed of car or applying brakes will stop the car but he does not
know about how on pressing accelerator the speed is actually increasing, he does not know
about the inner mechanism of the car or the implementation of accelerator, brakes etc in the
car.
The significance of forming abstractions while designing an object oriented system can be listed
as follows:
It manage complexity that arises due to interconnections of software components.
Set of procedure written by one programmer can be used by many other programmers
without knowing the exact details of implementation. They needed only the necessary
interface.
Data abstraction increases the reusability of the code by avoiding any chances of
redundancy.
It increases the readability of the code as it eliminates the possibility of displaying the
complex working of the code.
With the implementation of classes and objects, comes enhanced security. Since data
abstraction is a method of implementing classes and objects any denying access to other
classes of accessing the data members and member functions of the base class.
Helps the user to avoid writing the low level code.
It separates the entire program into code and implementation making it more
comprehensible.
5. What are the mechanism of data abstraction? What is the use of abstraction
mechanism in C++?Explain with example.[PU:2019 fall]
Data abstraction refers to providing only essential information to the outside world and hiding
their background details, i.e., to represent the needed information in program without
presenting the details. Data abstraction is a programming (and design) technique that relies on
the separation of interface and implementation
Let's take a real life example of AC, which can be turned ON or OFF, change the temperature,
change the mode, and other external components such as fan, swing. But, we don't know the
internal details of the AC, i.e., how it works internally. Thus, we can say that AC separates the
implementation details from the external interface.
Data Abstraction can be achieved in following ways:
Abstraction using classes
Abstraction in header files
Abstraction using access specifiers
Abstraction using classes: An abstraction can be achieved using classes. A class is used to group
all the data members and member functions into a single unit by using the access specifiers. A
class has the responsibility to determine which data member is to be visible outside and which
is not.
Abstraction in header files: An another type of abstraction is header file. For example, pow()
function available is used to calculate the power of a number without actually knowing which
algorithm function uses to calculate the power. Thus, we can say that header files hides all the
implementation details from the user.
Abstraction using Access specifiers: Access specifiers are the main pillar of implementing
abstraction in C++. We can use access specifiers to enforce restrictions on class members.
For example;
Members declared as public in a class, can be accessed from anywhere in the program.
Members declared as private in a class, can be accessed only from within the class. They
are not allowed to be accessed from any part of code outside the class.
1) Class can create a subclass that will inherit parent's properties and methods,
whereas Structure does not support the inheritance.
2) Structure members can be easily accessed by the structure variables in their
scope but class members doesn’t due to feature of data hiding.
3) Classes support polymorphism (late binding), whereas structure doesn’t.
4) Also we can use "this" pointers in classes due to which you don't have to
explicitly pass an object to a member function.
5) The structure data type cannot be treated like built in types while performing
arithmetic operations. But it is valid in class using the concept of operator
overloading.
For example:
struct complex
{
int real;
int imag;
}
struct complex c1,c2,c3;
c3=c1+c2; Is illegal .
2. Differentiate between structure and class. Why Class is preferred over structure?
Support your answer with suitable examples.[PU:2016 fall]
Structure
Class
Structures in C++ doesn't provide data hiding where as a class provides data hiding
A Structure is not secure and cannot hide its implementation details from the end user
while a class is secure and can hide its programming and designing details.
Classes support polymorphism (late binding), whereas structure doesn’t.
Class support inheritance but structure doesn’t.
"this" pointer will works only with class.
Class lets us to use constructors and destructors.
Access Modifiers or Access Specifiers in a class are used to set the accessibility of the class
members. That is, it sets some restrictions on the class members not to get directly accessed by
the outside functions.
There are 3 types of access modifiers available in C++.They are:
1) Public:
All the class members declared under public will be available to everyone. The data members
and member functions declared public can be accessed by other classes too. The public
members of a class can be accessed from anywhere in the program using the direct member
access operator (.) with the object of that class.
#include<iostream>
using namespace std;
class Rectangle
{
private:
float length,breadth,area;
public:
void setdata(float l,float b)
{
length=l;
breadth=b;
}
void disp_area()
{
area=length*breadth;
cout<<"Area="<<area<<endl;
}
};
int main()
{
Rectangle r;
r.setdata(10.5,6);
r.disp_area();
return 0;
}
Here, member function disp_area() is public so it is accessible outside class .But data member
length ,breadth and area being private they are not accessible outside class. Only member
function of that class disp_area() can access it.
Example:
#include <iostream>
using namespace std;
class A
{
protected:
int a, b;
public:
void setdata(int x, int y)
{
a = x;
b = y;
}
};
class B : public A
{
public:
void display()
{
cout << "value of a=" << a << endl;
cout << "value of b=" << b << endl;
cout << "Sum of two protected variables a and b = "<< a + b << endl;
}
};
int main()
{
B obj;
obj.setdata(4, 5);
obj.display();
return 0;
}
In above example , protected variable a and b is accessed by the derived class B.
From above discussion we can conclude that:
Accessible from Accessible from Accessible from
Access Specifier
own class derived class objects outside class
public yes yes yes
private yes no no
protected yes yes no
Data Hiding means protecting the data members of a class from an illegal or unauthorized
access from outside class. It ensures exclusive data access to class members and protects object
integrity by preventing unintended or intended changes.
By declaring the data member private in a class, the data members can be hidden from outside
the class. Those private data members cannot be accessed by the object directly.
#include<iostream>
using namespace std;
class Square
{
private:
int num;
public:
void getdata()
{
cout << "Enter the number"<<endl;;
cin>>num;
}
void display()
{
cout << "Square of a given number= "<< num*num<<endl;
}
};
int main()
{
Square obj;
obj.getdata();
obj.display();
return 0;
}
In the above example, the variable “num” is private. Hence this variable can be accessed only
by the member function of the same class and is not accessible from anywhere else. Hence
outside the classes will be unable to access this variable which is called data hiding. In this way
data hiding can be achieved.
In some situation non-member function need to access the private data of class or one class
wants to access private data of second class and second wants to access private data of first
class. This can achieve by using friend functions.
The non-member function that is “friendly” to a class, has full access rights to the private
members of the class.
For example when we want to compare two private data members of two different classes in
that case you need a common function which can make use of both the private variables of
different class. In that case we create a normal function and make friend in both the classes, as
to provide access of theirs private variables.
• It can access the private data member of class from outside the class
• Allows sharing private class information by a non-member function.
• It acts as the bridge between two classes by operating on their private data’s.
• It is able to access members without need of inheriting the class.
• It provides functions that need data which isn’t normally used by the class.
7. Does friend function violate the data hiding? Explain Briefly.[PU:2017 fall]
The concept of data hiding indicates that nonmember functions should not be able to access
the private data of class. But, it is possible with the help of a “friend function”. That means, a
function has to be declared as friend function to give it the authority to access to the private
data.
Hence, friend function is not a member function of the class but can access private members of
that class. So that’s why friend function violate data hiding.
3) The data under data hiding is always 3) The data under encapsulation may be
private and inaccessible. private or public.
2. Create a class called Employee with three data members (empno , name, address), a
function called readdata() to take in the details of the employee from the user, and a
function called displaydata() to display the details of the employee. In main, create
two objects of the class Employee and for each object call the readdata() and the
displaydata() functions. [PU:2005 fall]
#include<iostream>
using namespace std;
class student
{
private:
char stdnt_name[20];
char faculty[20];
int roll_no;
public:
void readdata();
void displaydata();
};
void student::readdata()
{
cout<<"Enter student name"<<endl;
cin>>stdnt_name;
cout<<"Enter student faculty"<<endl;
cin>>faculty;
cout<<"Enter student roll number"<<endl;
cin>>roll_no;
}
void student::displaydata()
{
cout<<"Name="<<stdnt_name<<endl;
cout<<"Roll no="<<roll_no<<endl;
cout<<"Faculty="<<faculty<<endl;
}
#include<iostream>
using namespace std;
class student
{
private:
char stdnt_name[20];
char faculty[20];
int roll_no;
public:
void readdata();
void displaydata();
};
void student::readdata()
{
cout<<"Enter student name"<<endl;
cin>>stdnt_name;
cout<<"Enter student faculty"<<endl;
cin>>faculty;
cout<<"Enter student roll number"<<endl;
cin>>roll_no;
}
5. WAP to perform the addition of time in hours, minutes and seconds format.
#include<iostream>
using namespace std;
class time
{
private:
int hours,minutes,seconds;
public:
void gettime(int h,int m,int s)
{
hours=h;
minutes=m;
seconds=s;
}
int main()
{
time t1,t2,t3;
t1.gettime(2,45,35);
t2.gettime(3,30,40);
t3.sum(t1,t2);
t3.display();
return 0;
}
6. WAP to perform the addition of time using the concept of returning object as
argument.
#include<iostream>
using namespace std;
class time
{
private:
int hours,minutes,seconds;
public:
void gettime(int h,int m,int s)
{
hours=h;
minutes=m;
seconds=s; }
void max(Rational r)
{
if(r.nume>r.deno)
{
cout<<"Maximum value="<<r.nume<<endl;
}
else
{
cout<<"Maximum value="<<r.deno<<endl;
}
}
int main()
{
Rational r;
r.getdata();
max(r);
return 0;
}
class A
{
private:
int x;
public:
void setdata(int num)
{
x=num;
}
friend void sum(A,B,C);
};
class B
{
private:
int y;
public:
void setdata(int num)
{
y=num;
}
friend void sum(A,B,C);
};
class C
{
private:
int z;
public:
void setdata(int num)
{
z=num;
}
friend void sum(A,B,C);
};
int main()
{
A p;
B q;
C r;
p.setdata(5);
q.setdata(10);
r.setdata(15);
sum(p,q,r);
return 0;
}
10. Write a program to find the largest of four integers .your program should have three
classes and each classes have one integer number.[PU:2014 spring]
#include<iostream>
using namespace std;
class Y;
class Z;
class X
{
private:
int a;
public:
void getdata()
{
cout<<"Enter first number"<<endl;
cin>>a;
}
friend void max(X,Y,Z);
};
class Z
{
private:
int c;
public:
void getdata()
{
cout<<"Enter third number"<<endl;
cin>>c;
}
friend void max(X,Y,Z);
};
11. WAP to add two complex numbers of two different classes using friend function.
#include<iostream>
using namespace std;
class complex2;
class complex1
{
private:
int real,imag;
public:
void getdata()
{
cout<<"Enter real and imaginary part"<<endl;
cin>>real>>imag;
}
void display()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
friend void addcomplex(complex1,complex2);
};
int main()
{
complex1 c1;
complex2 c2;
c1.getdata();
c2.getdata();
cout<<"first complex number"<<endl;
c1.display();
cout<<"second complex number"<<endl;
c2.display();
addcomplex(c1,c2);
return 0;
}
#include<iostream>
using namespace std;
class complex2;
class complex1
{
private:
int real,imag;
public:
void getdata()
{
cout<<"Enter real and imaginary part"<<endl;
cin>>real>>imag;
}
void display()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
friend class complex2;
};
class complex2
{
private:
int real,imag;
public:
void getdata()
{
cout<<"Enter real and imaginary part"<<endl;
cin>>real>>imag;
}
void display()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
void addcomplex(complex1 c1)
{
real=c1.real+real;
imag=c1.imag+imag;
}
};
#include<iostream>
using namespace std;
class customer
{
private:
float principle,rate,si;
int time;
public:
void setdata(float p,int t,float r=8);
void display();
};
void customer::setdata(float p,int t,float r)
{
principle=p;
time=t;
rate=r;
}
void customer::display()
{
si=(principle*time*rate)/100;
cout<<"Simple Interest="<<si<<endl;
}
14. Create classes called class1 and class2 with each of having one private member .Add
member function to set a value(say setvalue) one each class. Add one more function
max() that is friendly to both classes. max() function should compare two private
member of two classes and show maximum among them. Create one-one object of
each class and then set a value on them. Display the maximum number among
them.[PU:2015 fall,2016 fall]
#include<iostream>
#include<string.h>
using namespace std;
class City
{
private:
char CityName[20];
float DistFromKtm;
public:
void setdata(char cname[],float d)
{
strcpy(CityName,cname);
DistFromKtm=d;
}
void display()
{
cout<<"City name="<<CityName<<endl;
cout<<"Distance from ktm="<<DistFromKtm<<endl;
}
float AddDistance(City c1,City c2)
{
return (c1.DistFromKtm+c2.DistFromKtm);
}
};
int main()
{
City c1,c2,c3;
c1.setdata("Pokhara",250);
c2.setdata("Dhangadi",150);
cout<<"Information of first city"<<endl;
c1.display();
cout<<"Information of second city"<<endl;
c2.display();
cout<<"sum of DistFromKtm of Pokhara and Dhangadi="<<c3.AddDistance(c1,c2);
return 0;
}
18. WAP to read two complex numbers and a function that calls by passing references of
two objects rather than values of objects and add into third object and returns that
object.
#include<iostream>
using namespace std;
class Complex
{
private:
int real,imag;
public:
void getdata();
void display();
Complex sum( Complex &c1,Complex &c2);
};
void Complex::getdata()
{
cout<<"Enter real part and imaginary part"<<endl;
cin>>real>>imag;
}
void Complex::display()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
Complex Complex::sum( Complex &c1,Complex &c2)
{
Complex c3;
c3.real=c1.real+c2.real;
c3.imag=c1.imag+c2.imag;
return c3;
}
#include<iostream>
using namespace std;
float calculate(float principle,int time,float rate=15);
int main()
{
float p,r;
int t;
char ch;
cout<<"Enter principle and time"<<endl;
cin>>p>>t;
cout<<"Do you want to enter rate?"<<endl;
cin>>ch;
if(ch=='Y'||ch=='y')
{
cout<<"Enter rate"<<endl;
cin>>r;
cout<<"Interest="<<calculate(p,t,r)<<endl;
}
else
{
cout<<"Interest="<<calculate(p,t)<<endl;
}
return 0;
}
float calculate(float principle,int time,float rate)
{
return(principle*time*rate)/100.0;
}
#include<iostream>
using namespace std;
class comparison
{
private:
int x,y,max;
public:
void getdata()
{
cout<<"Enter two numbers"<<endl;
cin>>x>>y;
}
int largest()
{
max=(x>y)?x:y;
return max;
}
void print()
{
cout<<"Greater number="<<max<<endl;
}
};
int main()
{
comparison c1;
c1.getdata();
c1.largest();
c1.print();
return 0;
}
#include<iostream>
using namespace std;
class student
{
private:
char name[20];
int roll;
float me,mm,ms,total;
public:
void init()
{
cout<<"Enter roll number"<<endl;
cin>>roll;
cout<<"Enter name"<<endl;
cin>>name;
cout<<"Enter Marks in English,Math and science"<<endl;
cin>>me>>mm>>ms;
}
void calctotal()
{
total=me+mm+ms;
}
void display()
{
cout<<"Name:"<<name<<endl;
cout<<"RollNo:"<<roll<<endl;
cout<<"Marks in English:"<<me<<endl;
cout<<"Marks in Math:"<<mm<<endl;
cout<<"Marks in science:"<<ms<<endl;
cout<<"Total:"<<total<<endl;
}
};
int main()
{
student st;
st.init();
st.calctotal();
st.display();
return 0; }
Explanation:
Message passing formalization
st.getdata(100,200);
receiver Message arguments
int main()
{
student s;
s.getdata(325); //objects passing message
s.display(); //objects passing message
getch();
return 0;
}
Memory errors occur very commonly in programming, and they can affect application
stability and correctness. These errors are due to programming bugs. They can be hard to
reproduce, hard to debug, and potentially expensive to correct as well. Applications that
have memory errors can experience major problems.
Memory errors can be broadly classified into Heap Memory Errors and Stack Memory
Errors. Some of the challenging memory errors are:
1. Invalid Memory Access in stack and heap: This error occurs when a read or write
instruction references unallocated or deallocated memory.
2. Memory leaks
Memory leaks occur when memory is allocated but not released.
3. Mismatched Allocation/Deallocation
This error occurs when a deallocation is attempted with a function that is not the
logical counterpart of the allocation function used.
To avoid mismatched allocation/deallocation, ensure that the right de-allocator is
called. In C++, new[] is used for memory allocation and delete[] for freeing up.
4. Missing allocation
This error occurs when freeing memory which has already been freed. This is also
called "repeated free" or "double free".
5. Uninitialized Memory Access
This type of memory error will occur when an uninitialized variable is read in your
application. To avoid this type of memory error, always initialize variables before
using them.
Constructor is a ‘special’ member function whose task is to initialize the object of its
class.
It is not mandatory to use constructor in a class. As we know, Constructor are
invoked automatically when the objects are created.
So that object are initialized at the time of declaration. There is no need to separate
function call to initialize the object. Which reduces coding redundancy and minimizes
the programming error such as uninitialized memory access.
Constructor Destructor
Various situations when the copy constructor is called or automatically invoked are:
When compiler generates the temporary object.
When an object is constructed based on the object of the same class.
When an object of the class is passed to function by values as an argument.
When an object of the class is returned by value.
De-constructor is a member function that destroys the object that have been
created by a constructor.
Destructor doesn’t take any arguments, which means destructor cannot be
overloaded. So, that there will be only one destructor in a class.
Destructors are usually used to deallocate memory and do other cleanup for a class
object and its class members when the object is destroyed. A destructor is called for
a class object when that object passes out of scope or is explicitly deleted.
So, that there cannot be more than one destructor ( two destructor ) in a same class.
A constructor is allowed to accept the arguments as the arguments can be used to initialize
the data members of the class.
A destructor does not accept any arguments as its only work is to deallocate the memory of
the object.
In class, there can be multiple constructors which are identified by the number arguments
passed.
In class, there is only one destructor.
Constructors can be overload to perform different action under the name of the same
constructor whereas, destructors cannot be overloaded.
Example:
#include <iostream>
using namespace std;
class test
{
private:
int a;
public:
test()
{
a=10;
cout<<"Default constructor is called"<<endl;
}
test(int x)
{
a=x;
cout<<"Parameterized constructor is called"<<endl;
}
~test()
{
cout<<"Destructor is called"<<endl;
}
void display()
{
cout<<"value of a="<<a<<endl;
}
};
8. What do you mean by stack vs Heap? Explain the memory recovery. Explain the
use
of new and delete operator. [PU:2009 spring]
Stack
It's a region of computer's memory that stores temporary variables created
by each function (including the main() function).
The stack is a "Last in First Out" data structure and limited in size. Every time
a function declares a new variable, it is "pushed" (inserted) onto the stack.
Every time a function exits, all of the variables pushed onto the stack by that
function, are freed or popped (that is to say, they are deleted).
Once a stack variable is freed, that region of memory becomes available for
other stack variables.
Heap
The heap is a region of computer's memory that is not managed
automatically and is not as tightly managed by the CPU.
We must allocate and de-allocate variable explicitly. (for allocating
variable new and for freeing variables delete operator is used.
It does not have a specific limit on memory size.
Memory recovery
new is used to allocate memory blocks at run time (dynamically). While, delete is
used to de-allocate the memory which has been allocated dynamically.
#include <iostream>
using namespace std;
int main ()
{
int i,n;
int *ptr;
int sum=0;
cout << "How many numbers would you like to Enter? ";
cin >>n;
ptr= new int[n];
9. What are the advantages of dynamic memory allocation? Explain with suitable
example. [PU:2016 spring]
The main advantage of using dynamic memory allocation is preventing the wastage
of memory or efficient utilization of memory. Let us consider an example:
In static memory allocation the memory is allocated before the execution of program
begins (During compilation).In this type of allocation the memory cannot be resized
after initial allocation. So it has some limitations. Like
Wastage of memory
Overflow of memory
eg. int num[100];
Here, the size of an array has been fixed to 100.If we just enter to 10 elements only,
then their will be wastage of 90 memory location and if we need to store more than
100
elements there will be memory overflow.
Example:
Program to find the sum of two Complex number using the concept of dynamic
constructor
#include<iostream>
using namespace std;
class complex
{
int *real,*imag;
public:
complex()
{
real=new int;
imag=new int;
*real=0;
*imag=0;
}
complex(int r,int i)
{
real=new int;
*real=r;
imag=new int;
*imag=i;
}
void display()
{
cout<<*real<<"+i"<<*imag<<endl;
}
void addcomplex(complex c1,complex c2)
{
*real=*c1.real+*c2.real;
*imag=*c1.imag+*c2.imag;
}
};
#include<iostream>
#include<string.h>
using namespace std;
class stringc
{
char *name;
int length;
public :
stringc()
{
length=0;
name=new char[length + 1];
}
stringc(char s[])
{
length=strlen(s);
name=new char[length+1];
strcpy(name,s);
}
void join(stringc &a,stringc &b)
{
length=a.length+b.length;
delete name;
name=new char[length+1];
strcpy(name,a.name);
strcat(name,b.name);
}
};
int main ()
{
stringc s1("Hello");
stringc s2("Nepal");
stringc s3;
s3.join(s1,s2);
s3.display();
return 0;
return 0;
}
class simple_interest
{
float principle , time, rate ,interest;
public:
simple_interest (float a, float b, float c)
{
principle = a;
time =b;
rate = c;
}
void display ( ) {
#include<iostream>
using namespace std;
class Employee
{
private:
char name[20];
int age;
float salary;
static int count;
public:
void getinfo()
{
cout<<"Enter name of employee"<<endl;
cin>>name;
cout<<"Enter age"<<endl;
cin>>age;
cout<<"Enter salary"<<endl;
cin>>salary;
count++;
}
void dispinfo()
{
cout<<"Name:"<<name<<endl;
cout<<"Age:"<<age<<endl;
cout<<"Salary:"<<salary<<endl;
}
static void disptotal()
{
cout<<"Total number of employees are:"<<count<<endl;
}
};
int Employee::count;
#include<iostream>
using namespace std;
class rectangle
{
private:
int length,breadth,area;
public:
rectangle(int l,int b)
{
length=l;
breadth=b;
}
void calc()
{
area=length*breadth;
}
void display()
{
cout<<"Area of Rectangle="<<area<<endl;
}
};
3) WAP to initialize name, roll and marks of student using constructor and display the
obtained information.
#include<iostream>
#include<string.h>
using namespace std;
class student
{
private:
char name[20];
int roll;
float marks;
public:
student(char n[],int r,float m)
{
strcpy(name,n);
roll=r;
marks=m;
}
void display()
{
cout<<"Name:"<<name<<endl;
cout<<"Roll no:"<<roll<<endl;
cout<<"Marks:"<<marks<<endl;
}
};
int main()
{
student st("Ram",7,88.5);
st.display();
}
#include<iostream>
#include<string.h>
using namespace std;
class student
{
private:
char name[20];
int roll;
float me,mm,mo,total,avg;
public:
student(char n[],int r,float e,float m,float o)
{
strcpy(name,n);
roll=r;
me=e;
mm=m;
mo=o;
}
void calculate()
{
total=me+mm+mo;
avg=total/3;
}
void print()
{
cout<<"Name:"<<name<<endl;
cout<<"Roll no:"<<roll<<endl;
cout<<"Total:"<<total<<endl;
cout<<"Average:"<<avg<<endl;
}
};
5) WAP to perform the addition of complex number using the concept of constructor.
#include<iostream>
using namespace std;
class complex
{
private:
int real,imag;
public:
complex()
{
real=2;
imag=4;
}
complex(int r,int i)
{
real=r;
imag=i;
}
void addcomplex(complex c1,complex c2)
{
real=c1.real+c2.real;
imag=c1.imag+c2.imag;
}
int main()
{
complex c1;
complex c2(10,20);
complex c3;
cout<<"First complex number="<<endl;
c1.display();
cout<<"Second complex number="<<endl;
c2.display();
c3.addcomplex(c1,c2);
cout<<"sum="<<endl;
c3.display();
return 0;
}
#include<iostream>
using namespace std;
class complex
{
private:
int real,imag;
public:
complex(int r,int i)
{
real=r;
imag=i;
}
complex(complex &x)
{
real=x.real;
imag=x.imag;
}
#include<iostream>
#include<string.h>
using namespace std;
class strings
{
char *name;
int length;
public:
strings()
{
length=0;
name=new char[length+1];
}
strings (char *s)
{
length=strlen(s);
name=new char[length+1];
strcpy(name,s);
}
void display()
{
cout<<name<<endl;
}
9) Write a simple program using of dynamic memory allocation which should include
calculation of marks of 3 subjects of n students and displaying the result as pass or fail
and name, roll. Pass mark is 45 out of 100 in each subject.
10) Write a program to find the difference of complex number using the concept of
constructors. Input the values from main () and pass argument to the constructor.
#include<iostream>
using namespace std;
class complex
{
private:
int real,imag;
public:
complex()
{
}
complex(int r,int i)
{
real=r;
imag=i;
}
void diffcomplex(complex c1,complex c2)
{
int main()
{
int real1,imag1,real2,imag2;
cout<<"Enter the real and imaginary part of first complex number"<<endl;
cin>>real1>>imag1;
cout<<"Enter the real and imaginary part of second complex number"<<endl;
cin>>real2>>imag2;
complex c1(real1,imag1);
complex c2(real2,imag2);
complex c3;
cout<<"First complex number="<<endl;
c1.display();
cout<<"Second complex number="<<endl;
c2.display();
c3.diffcomplex(c1,c2);
cout<<"Difference of complex number="<<endl;
c3.display();
return 0;
}
Using the concept of inheritance the data member and member function of classes can
be reused. When once a class has been written and tested, it can be adapted by another
programmer to suit their requirements. This is basically done by creating new classes,
reusing the properties of the existing ones. This mechanism of deriving a new class from
an old one is called inheritance.
A derived class includes all features of the base class and then it can add additional
features specific to derived class.
Example:
#include<iostream>
using namespace std;
class Sum
{
protected:
int a,b;
public:
void getdata()
{
cout<<"Enter two numbers"<<endl;
cin>>a>>b;
}
void display()
{
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
}
};
class Result:public Sum
{
private:
int total;
public:
void disp_result()
{
total=a+b;
cout<<"sum="<<total<<endl;
}
};
Here, In above example Sum is base class and Result is derived class. The data member named
a and b and member function display () of base class are inherited and they are used by using
the object of derived class named Result. Hence, we can see that inheritance provides
reusability.
3. How are arguments are sent to base constructors in multiple inheritance ?Who is
responsibility of it.[PU:2013 spring]
In Multiple Inheritance arguments are sent to base class in the order in which they
appear in the declaration of the derived class.
For example:
Class gamma: public beta, public alpha
{
}
Order of execution
beta(); base constructor (first)
alpha(); base constructor(second)
gamma();derived (last)
The constructor of derived class is responsible to supply values to the base class
constructor.
Program:
#include<iostream>
using namespace std;
Compiled By: Pradip Paudel Page:3
class alpha
{
int x;
public:
alpha(int a)
{
x=a;
cout<<"Alpha is initialized"<<endl;
}
void showa()
{
cout<<"x="<<x<<endl;
}
};
class beta
{
int y;
public:
beta(int b)
{
y=b;
cout<<"Beta is initialized"<<endl;
}
void showb()
{
cout<<"y="<<y<<endl;
}
};
class gamma:public beta,public alpha
{
int z;
public:
gamma(int a,int b,int c):alpha(a),beta(b)
{
z=c;
cout<<"Gamma is initialized"<<endl;
}
void showg()
{
cout<<"z="<<z<<endl;
}
};
Beta is initialized
Alpha is initialized
Gamma is initialized
x=5
y=10
z=15
Here, beta is initialized first although it appears second in the derived constructor as it has been
declared first in the derived class header line
class gamma: public beta, public alpha
{}
If we change the order to
4. Class ‘Y’ has been derived from class ‘X’ .The class ‘Y’ does not contain any data
members of its own. Does the class ‘Y’ require constructors? If yes why.[PU:2013
spring]
When Class ‘Y’ has been derived from class ‘X’ and class ‘Y’ does not contain any data members
of its own then,
It is mandatory have constructor in derived class ‘Y’, whether it has data members to be
initialized or not, if there is constructor with arguments(parameterized constructor) in
base class ‘X’.
It not necessary to have constructor in derived class ‘Y’ if base class ‘X’ does not contain
a constructor with arguments (parameterized constructor).
Derived class constructor is used to provide the values to the base class constructor.
}
};
int main()
{
Y obj(5);
obj.display();
return 0;
}
Here, in above example, class ‘Y’ does not have any data members but there is a parameterized
constructor in class ‘X’ so, there is necessary to have constructor in class ‘Y’.
In this figure, we see that there are two types of flights so we made a flight class which will
contain common properties and then we has an international and domestic class which are an
extension of flight class and will have properties of flight as well as their own. Here flight is the
parent/superclass and the other two are child/subclass. International Flight “is-a” flight as well
as the domestic flight.
#include <iostream>
#include <conio.h>
using namespace std;
class Student_info
{
char name[25];
int age;
public:
void get_info()
{
cout<<"Enter name and age of student"<<endl;
cin>>name>>age;
}
void disp_info()
{
cout<<"Name of student:"<<name<<endl;
cout<<"Age of student:"<<age<<endl;
}
};
class Faculty
{
char faculty[20];
public:
void get_faculty()
{
cout<<"Enter Faculty of student"<<endl;
cin>>faculty;
}
void disp_faculty()
{
cout<<"Faculty of student:"<<faculty<<endl;
}
};
void disp_attendance()
{
cout<<"Student's attendance percentage ="<<attendance<<endl;
}
};
int main()
{
int i,n;
Attendance a[50];
cout<<"Enter Number of students"<<endl;
cin>>n;
for(i=0;i<n;i++)
{
cout<<"Enter information of student:"<<i+1<<endl;
a[i].get_info();
a[i].get_faculty();
a[i].get_attendance();
}
for(i=0;i<n;i++)
{
cout<<"Information of student:"<<i+1<<endl;
a[i].disp_info();
a[i].disp_faculty();
a[i].disp_attendance();
}
return 0;
}
#include<iostream>
#include<string.h>
using namespace std;
class University
{
private:
char uname[20];
char location[20];
public:
University(char un[],char loc[])
{
strcpy(uname,un);
strcpy(location,loc);
}
#include<iostream>
using namespace std;
class Staff
{
protected:
char name[20];
int code;
public:
void get_staff()
{
cout<<"Enter Name and code of staff"<<endl;
cin>>name>>code;
}
void disp_staff()
{
cout<<"Name="<<name<<endl;
cout<<"Code="<<code<<endl;
}
};
t.get_staff();
t.get_teacher();
t.disp_staff();
t.disp_teacher();
o.get_staff();
o.get_officer();
o.disp_staff();
o.disp_officer();
c.get_staff();
c.get_typist();
c.get_casual();
c.disp_staff();
c.disp_typist();
c.disp_casual();
return 0;
}
6. The following figure shows minimum information required for each class.
Write a Program to realize the above program with necessary member functions to create the
database and retrieve individual information
#include<iostream>
using namespace std;
class Person
{
protected:
char name[20];
int code;
};
#include<iostream>
#include<string.h>
using namespace std;
8. Write a program that allow you to book a ticket for person and use two classes PERSON,
RESERVATION. Class RESERVATION is composite class/ container class.
#include<iostream>
using namespace std;
class Person
{
char name[20];
int age;
public:
void getdata()
{
cout<<"Enter name and age of person"<<endl;
cin>>name>>age;
}
9. The following figure shows the minimum information required for each class. Write a
program to realize the above program with necessary member functions to create the
database and retrieve individual information .Every class should contain at least one
constructor and should be inherited to other classes as well.[PU:2010 spring][PU 2009 fall]
10. Develop a complete program for an institution, which wishes to maintain a database of its
staff. The database is divided into number of classes whose hierarchical relationship is shown
in the following diagram. specify all classes and define constructors and functions to create
database and retrieve the individual information as per requirements.
#include<iostream>
#include<string.h>
using namespace std;
class STAFF
{
private:
int staff_id;
char name[20];
public:
STAFF(int sid,char sn[])
{
staff_id=sid;
strcpy(name,sn);
}
};
class ADMINISTRATIVE_STAFF:public STAFF
{
char post[20];
char department[20];
public:
ADMINISTRATIVE_STAFF(int sid,char sn[],char p[],char dept[]):STAFF(sid,sn)
{
strcpy(post,p);
strcpy(department,dept);
}
void display()
{
cout<<"Post:"<<post<<endl;
cout<<"Department:"<<department<<endl;
}
};
int main()
{
LECTURER l(101,"Pradip Paudel","C programming","Computer");
l.STAFF::display();
l.display();
ADMINISTRATIVE_STAFF a(212,"Ekraj Acharaya","Admin","Administration");
a.STAFF::display();
a.display();
LIBRARIAN lib(314,"Sita sharma","Morning");
lib.STAFF::display();
lib.display();
return 0;
}
11. Develop a complete program for an institution which wishes to maintain a database of its
staff. Declare a base class STAFF which include staff_id and name.Now develop a records for
the following staffs with the given information below.
Lecturer(subject,department)
Administrative staff (Post,department)
};
void get_administrative()
{
cout<<"Enter post"<<endl;
cin>>post;
cout<<"Enter department"<<endl;
cin>>department;
}
void display_administrative()
{
cout<<"Post:"<<post<<endl;
cout<<"Department:"<<department<<endl;
}
};
int main()
{
LECTURER l;
l.get_staff();
l.get_lecturer();
l.display_staff();
l.display_lecturer();
ADMINISTRATIVE_STAFF a;
a.get_staff();
a.get_administrative();
a.display_staff();
a.display_administrative();
return 0;
}
#include<iostream>
using namespace std;
class Student
{
private:
char name[20];
int roll;
public:
void get_student()
{
cout<<"Enter name and roll no"<<endl;
cin>>name>>roll;
}
void disp_student()
{
cout<<"Name="<<name<<endl;
cout<<"Rollno="<<roll<<endl;
}
};