Q.1
A.1.
.(a) What is Object Oriented Programming ( OOP) paradigm?
Explain basic concepts OOP.
The object-oriented paradigm took its shape from the initial
concept of a new programming approach, while the interest in design and
analysis methods came much later.
·
The first object–oriented language was Simula (Simulation of real
systems) that was developed in 1960 by researchers at the Norwegian Computing
Center.
·
In 1970, Alan Kay and his research group at Xerox PARK created a
personal computer named Dynabook and the first pure object-oriented programming
language (OOPL) - Smalltalk, for programming the Dynabook.
·
In the 1980s, Grady Booch published a paper titled Object Oriented
Design that mainly presented a design for the programming language, Ada. In the
ensuing editions, he extended his ideas to a complete object–oriented design
method.
·
In the 1990s, Coad incorporated behavioral ideas to
object-oriented methods.
The other significant innovations were Object Modelling Techniques
(OMT) by James Rumbaugh and Object-Oriented Software Engineering (OOSE) by Ivar
Jacobson.
The Objects Oriented Programming
(OOP) is constructed over four major principles:
Encapsulation, Data Abstraction, Polymorphism and Inheritance.
1. Encapsulation:
Encapsulation means that the internal representation of an object is generally
hidden from view outside of the object’s definition. Typically, only the
object’s own methods can directly inspect or manipulate its fields.
Encapsulation is the hiding of
data implementation by restricting access to accessors and mutators.
An accessor is a method that is used to ask an
object about itself. In OOP, these are usually in the form of properties, which
have a get method, which is an accessor method.
However, accessor methods are not restricted to properties and can be any
public method that gives information about the state of the object.
A Mutator is public method
that is used to modify the state of an object, while hiding the implementation
of exactly how the data gets modified. It’s the set method that lets the caller modify the
member data behind the scenes.
Hiding the internals of the object protects its integrity by
preventing users from setting the internal data of the component into an
invalid or inconsistent state. This type of data protection and
implementation protection is called Encapsulation.
A benefit of encapsulation is that
it can reduce system complexity.
2. Abstraction
Data abstraction and encapuslation are closely tied together, because a simple
definition of data abstraction is the development of classes, objects, types in
terms of their interfaces and functionality, instead of their implementation
details. Abstraction denotes a model, a view, or some other focused
representation for an actual item.
“An abstraction denotes the
essential characteristics of an object that distinguish it from all other kinds
of object and thus provide crisply defined conceptual boundaries, relative to
the perspective of the viewer.” — G. Booch
In short, data abstraction is
nothing more than the implementation of an object that contains the same
essential properties and actions we can find in the original object we are
representing.
3. Inheritance
Inheritance is a way to reuse code of existing objects, or to establish a
subtype from an existing object, or both, depending upon programming language
support. In classical inheritance where objects are defined by classes, classes
can inherit attributes and behavior from pre-existing classes called base
classes, superclasses, parent classes or ancestor classes. The resulting
classes are known as derived classes, subclasses or child classes. The relationships
of classes through inheritance gives rise to a hierarchy.
Subclasses and Superclasses
A subclass is a modular, derivative class that inherits one or more properties
from another class (called the superclass). The properties commonly include class
data variables, properties, and methods or functions. The superclass
establishes a common interface and foundational functionality, which
specialized subclasses can inherit, modify, and supplement. The software
inherited by a subclass is considered reused in the subclass.
In some cases, a subclass may customize or redefine a method inherited from the
superclass. A superclass method which can be redefined in this way is called a
virtual method.
4. Polymorphism
Polymorphism means one name, many forms. Polymorphism manifests itself by
having multiple methods all with the same name, but slightly different
functionality.
There are 2 basic types of polymorphism.
Overriding, also called run-time
polymorphism. Method will be used for method overriding is determined at
runtime based on the dynamic type of an object.
Overloading,
which is referred to as compile-time polymorphism. For method overloading, the
compiler determines which method will be executed, and this decision is made
when the code gets compiled.
(b) Explain different data types available in C++ programming.
Encapsulation, Data Abstraction, Polymorphism and Inheritance.
Encapsulation means that the internal representation of an object is generally hidden from view outside of the object’s definition. Typically, only the object’s own methods can directly inspect or manipulate its fields.
Data abstraction and encapuslation are closely tied together, because a simple definition of data abstraction is the development of classes, objects, types in terms of their interfaces and functionality, instead of their implementation details. Abstraction denotes a model, a view, or some other focused representation for an actual item.
Inheritance is a way to reuse code of existing objects, or to establish a subtype from an existing object, or both, depending upon programming language support. In classical inheritance where objects are defined by classes, classes can inherit attributes and behavior from pre-existing classes called base classes, superclasses, parent classes or ancestor classes. The resulting classes are known as derived classes, subclasses or child classes. The relationships of classes through inheritance gives rise to a hierarchy.
A subclass is a modular, derivative class that inherits one or more properties from another class (called the superclass). The properties commonly include class data variables, properties, and methods or functions. The superclass establishes a common interface and foundational functionality, which specialized subclasses can inherit, modify, and supplement. The software inherited by a subclass is considered reused in the subclass.
In some cases, a subclass may customize or redefine a method inherited from the superclass. A superclass method which can be redefined in this way is called a virtual method.
Polymorphism means one name, many forms. Polymorphism manifests itself by having multiple methods all with the same name, but slightly different functionality.
Overriding, also called run-time polymorphism. Method will be used for method overriding is determined at runtime based on the dynamic type of an object.
Overloading, which is referred to as compile-time polymorphism. For method overloading, the compiler determines which method will be executed, and this decision is made when the code gets compiled.
While doing programming in any programming
language, you need to use various variables to store various information.
Variables are nothing but reserved memory locations to store values. This means
that when you create a variable you reserve some space in memory.
You may like to store information of various data
types like character, wide character, integer, floating point, double floating
point, boolean etc. Based on the data type of a variable, the operating system
allocates memory and decides what can be stored in the reserved memory.
Built in Data Types
These are the data types which are predefined and are wired
directly into the compiler. eg: int, char etc.
User defined or Abstract data types
These are the type, that user creates as a class. In C++ these are
classes where as in C it was implemented by structures.
Basic Built in types
char |
for
character storage ( 1 byte )
|
int |
for
integral number ( 2 bytes )
|
float |
single
precision floating point ( 4 bytes )
|
double |
double
precision floating point numbers ( 8 bytes )
|
Example :
char a = 'A'; // character typeint a = 1; // integer type
float a = 3.14159; // floating point type
double a = 6e-4; // double type (e is for exponential)
Other Built in types
bool |
Boolean
( True or False )
|
void |
Without
any Value
|
wchar_t |
Wide
Character
|
Enum as Data type
Enumerated type declares a new type-name and a sequence of value
containing identifiers which has values starting from 0 and incrementing by 1
every time.
For Example :
enum day(mon, tues, wed, thurs, fri) d;
Here an enumeration of days is defined with variable d. mon will hold value 0, tue will have 1 and so on. We can also
explicitly assign values, like, enum
day(mon, tue=7, wed);
. Here, mon will be 0, tue is assigned 7, so wed will have value 8.
enum
day(mon, tue=7, wed);
. Here, mon will be 0, tue is assigned 7, so wed will have value 8.
Modifiers
Specifiers modify the meanings of the predefined built-in data
types and expand them to a much larger set. There are four data type modifiers
in C++, they are :
1.
long
2.
short
3.
signed
4.
unsigned
Below mentioned are some important points you must know about the
modifiers,
·
long and short modify the maximum and minimum values
that a data type will hold.
·
A plain int must have a minimum size of short.
·
Size hierarchy : short int
< int < long int
·
Size hierarchy for floating point numbers is : float < double < long
double
·
long float is not a legal type and there are no short floating point numbers.
·
Signed types includes both positive and negative numbers and is the
default type.
·
Unsigned, numbers are always
without any sign, that is always positive.
(c) Explain the use of followings in C++ programming with an
example program for each.
short int
< int < long int
float < double < long
double
(i) while
(ii) for
There are circumstances were you want
to do the same thing many times. For instance you want to
print the same words ten times. You could type ten cout statements, but it is
easier to use a loop, such as a “for loop” or a “while loop.” The only thing
you have to do is to setup a loop that execute the same cout statement ten
times.
There are three basic types of loops
which are:
§ “for loop”
§ “while loop”
§ “do while loop”
The for loop
The “for loop” loops from one number to
another number and increases by a specified value each time.
The “for loop” uses the following structure:
for
(Start value; end condition; increase value)
statement(s);
Look at the example below:
#include<iostream>
using
namespace std;
int
main()
{
int
i;
for
(i = 0; i < 10; i++)
{
cout
<< "Hello" << "\n";
cout
<< "There" << "\n";
}
return
0;
}
Note: A
single instruction can be placed behind the “for loop” without the curly
brackets.
Lets look at the “for loop” from the
example: We first start by setting the variable i to 0. This is where we
start to count. Then we say that the for loop must run if the counter i is
smaller then ten. Last we say that every cycle i must be increased by one
(i++).
In the example we used i++ which is the
same as using i = i + 1. This is called incrementing. The instruction i++ adds
1 to i. If you want to subtract 1 from i you can use i–. It is also possible to
use ++i or -i. The difference is is that with ++i the one is added before the
“for loop” tests if i < 10. With i++ the one is added after the test i <
10.
The while loop
The while loop can be used if you don’t
know how many times a loop must run.
Here is an example:
#include<iostream>
using
namespace std;
int
main()
{
int
counter, howmuch;
cin
>> howmuch;
counter
= 0;
while
( counter < howmuch)
{
counter++;
cout
<< counter << '\n';
}
return
0;
}
Lets take a look at the example: First
you must always initialize the counter before the while loop starts ( counter =
1). Then the while loop will run if the variable counter is smaller then the
variable “howmuch”. If the input is ten, then 1 through 10 will be printed on
the screen. A last thing you have to remember is to increment the counter
inside the loop (counter++). If you forget this the loop becomes infinitive.
(d) Explain use of any two I/O formatting flags in C++ with
example.
print the same words ten times. You could type ten cout statements, but it is easier to use a loop, such as a “for loop” or a “while loop.” The only thing you have to do is to setup a loop that execute the same cout statement ten times.
The “for loop” uses the following structure:
single instruction can be placed behind the “for loop” without the curly brackets.
Here is an example:
C++ defines some format flags for standard input
and output, which can be manipulated with the flags(), setf(), and unsetf() functions. For example,
cout.setf(ios::left);
turns on left justification for all output directed
to cout.
Flag
|
Meaning
|
boolalpha
|
Boolean
values can be input/output using the words "true" and
"false".
|
dec
|
Numeric
values are displayed in decimal.
|
fixed
|
Display
floating point values using normal notation (as opposed to scientific).
|
hex
|
Numeric
values are displayed in hexidecimal.
|
internal
|
If a
numeric value is padded to fill a field, spaces are inserted between the sign
and base character.
|
left
|
Output
is left justified.
|
oct
|
Numeric
values are displayed in octal.
|
right
|
Output
is right justified.
|
scientific
|
Display
floating point values using scientific notation.
|
showbase
|
Display
the base of all numeric values.
|
showpoint
|
Display
a decimal and extra zeros, even when not needed.
|
showpos
|
Display
a leading plus sign before positive numeric values.
|
skipws
|
Discard
whitespace characters (spaces, tabs, newlines) when reading from a stream.
|
unitbuf
|
Flush
the buffer after each insertion.
|
uppercase
|
Display
the "e" of scientific notation and the "x" of hexidecimal
notation as capital letters.
|
You can also manipulate flags indirectly, using the
following manipulators. Most programmers
are familiar with the endl manipulator, which
might give you an idea of how manipulators are used. For example, to set the dec flag, you might use the following
command:
cout << dec;
Manipulators
defined in <iostream>
|
|||
Manipulator
|
Description
|
Input
|
Output
|
boolalpha
|
Turns
on the boolalpha flag
|
X
|
X
|
dec
|
Turns
on the dec flag
|
X
|
X
|
endl
|
Output
a newline character, flush the stream
|
X
|
|
ends
|
Output
a null character
|
X
|
|
fixed
|
Turns
on the fixed flag
|
X
|
|
flush
|
Flushes
the stream
|
X
|
|
hex
|
Turns
on the hex flag
|
X
|
X
|
internal
|
Turns
on the internal flag
|
X
|
|
left
|
Turns
on the left flag
|
X
|
|
noboolalpha
|
Turns
off the boolalpha flag
|
X
|
X
|
noshowbase
|
Turns
off the showbase flag
|
X
|
|
noshowpoint
|
Turns
off the showpoint flag
|
X
|
|
noshowpos
|
Turns
off the showpos flag
|
X
|
|
noskipws
|
Turns
off the skipws flag
|
X
|
|
nounitbuf
|
Turns
off the unitbuf flag
|
X
|
|
nouppercase
|
Turns
off the uppercase flag
|
X
|
|
oct
|
Turns
on the oct flag
|
X
|
X
|
right
|
Turns
on the right flag
|
X
|
|
scientific
|
Turns
on the scientific flag
|
X
|
|
showbase
|
Turns
on the showbase flag
|
X
|
|
showpoint
|
Turns
on the showpoint flag
|
X
|
|
showpos
|
Turns
on the showpos flag
|
X
|
|
skipws
|
Turns
on the skipws flag
|
X
|
|
unitbuf
|
Turns
on the unitbuf flag
|
X
|
|
uppercase
|
Turns
on the uppercase flag
|
X
|
|
ws
|
Skip
any leading whitespace
|
X
|
Manipulators
defined in <iomanip>
|
|||
Manipulator
|
Description
|
Input
|
Output
|
resetiosflags(
long f )
|
Turn
off the flags specified by f
|
X
|
X
|
setbase(
int base )
|
Sets
the number base to base
|
X
|
|
setfill(
int ch )
|
Sets
the fill character to ch
|
X
|
|
setiosflags(
long f )
|
Turn on
the flags specified by f
|
X
|
X
|
setprecision(
int p )
|
Sets
the number of digits of precision
|
X
|
|
setw(
int w )
|
Sets
the field width to w
|
X
|
The I/O stream state flags tell you the current
state of an I/O stream. The flags are:
Flag
|
Meaning
|
badbit
|
a fatal
error has occurred
|
eofbit
|
EOF has
been found
|
failbit
|
a
nonfatal error has occurred
|
goodbit
|
no
errors have occurred
|
The I/O stream mode flags allow you to access files
in different ways. The flags are:
Mode
|
Meaning
|
ios::app
|
append
output
|
ios::ate
|
seek to
EOF when opened
|
ios::binary
|
open
the file in binary mode
|
ios::in
|
open the
file for reading
|
ios::out
|
open
the file for writing
|
ios::trunc
|
overwrite
the existing file
|
Q.2. (a) What is constructor? Define Book class with the basic features of a book. Define the default constructor, parameterised constructor, member functions display_book_details() for displaying the details of book. Use appropriate access control specifiers in this program.
A.2.(a)
- Constructor is a special member
function of class having same name of class
- It is called automatically when create
an object.
- It doesn’t have any return type even
void.
- It can be parameterized.
- It can be overloaded.
- it can has default arguments
- It is declare as public always.
Default constructor: - constructors with no arguments or all
are default arguments are called default
constructor. If a constructor is not declare in class then
compiler define it implicitly is also called default constructor.
class sum
{
sum() //default constructor
or
sum(int a=3, int b=4)
}
Example:-
#include<iostream.h>
#include<conio.h>
#include<string.h>
class book
{
int bid;
char bname[10],auth[10];
int price;
public:
book(int id, char *bn,char *au,int p)
{
bid=id;
strcpy(bname,bn);
strcpy(auth,au);
price=p;
}
void disp_book_details();
};
void book::disp_book_details()
{
cout<<"Book ID="<<bid<<endl;
cout<<"Book Name="<<bname<<endl;
cout<<"Author="<<auth<<endl;
cout<<"Price="<<price<<endl;
}
void main()
{
book ob(1,"Word","Deep",120);
ob.disp_book_details();
getch();
}
(b) Explain the following in detail with the help of examples, in
context of C++ programming.
A.2.(b) (i) Destructor
The Class Destructor
A destructor is a special member function of a
class that is executed whenever an object of it's class goes out of scope or
whenever the delete expression is applied to a pointer to the object of that
class.
A destructor will have exact same name as the class prefixed with
a tilde (~) and it can neither return a value nor can it take any parameters.
Destructor can be very useful for releasing resources before coming out of the
program like closing files, releasing memories etc.
Following example explains the concept of destructor:
#include <iostream>
using namespace std;
class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // This is the constructor declaration
~Line(); // This is the destructor: declaration
private:
double length;
};
// Member functions definitions including constructor
Line::Line(void) {
cout << "Object is being created" << endl;
}
Line::~Line(void) {
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}
// Main function for the program
int main( ) {
Line line;
// set line length
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
When the above code is compiled and executed, it produces the
following result:
Object is being created
Length of line : 6
Object is being deleted
(ii) Virtual Function
Virtual Functions
Virtual Function is a function in base class, which is overrided
in the derived class, and which tells the compiler to perform Late Binding on this function.
Virtual
Keyword is used to make a member function of the base class
Virtual. Late Binding
In Late Binding function call is resolved at runtime. Hence, now compiler determines the type of object at runtime, and then binds the function call. Late Binding is also called Dynamic Binding or Runtime Binding.
Problem without Virtual Keyword class Base
{
public:
void show()
{
cout << "Base class";
}
};
class Derived:public Base
{
public:
void show()
{
cout << "Derived Class";
}
}
int main()
{
Base* b; //Base class pointer
Derived d; //Derived class object
b = &d;
b->show(); //Early Binding Ocuurs
}
Output : Base class
When we use Base class's pointer to hold Derived class's object, base class pointer or reference will always call the base version of the function
Using Virtual Keyword
We can make base class's methods virtual by using virtual keyword while declaring them. Virtual keyword will lead to Late Binding of that method. class Base
{
public:
virtual void show()
{
cout << "Base class";
}
};
class Derived:public Base
{
public:
void show()
{
cout << "Derived Class";
}
}
int main()
{
Base* b; //Base class pointer
Derived d; //Derived class object
b = &d;
b->show(); //Late Binding Ocuurs
}
Output : Derived class
On using Virtual keyword with Base class's function, Late Binding
takes place and the derived version of function will be called, because base
class pointer pointes to Derived class object.
Using Virtual Keyword and Accessing Private Method of Derived
class
We can call private function of derived class from the
base class pointer with the help of virtual keyword. Compiler checks for access
specifier only at compile time. So at run time when late binding occurs it does
not check whether we are calling the private function or public function.
#include using namespace std;
class A
{
public:
virtual void show()
{
cout << "Base class\n";
}
};
class B: public A
{
private:
virtual void show()
{
cout << "Derived class\n";
}
};
int main()
{
A *a;
B b;
a = &b;
a -> show();
}
Output : Derived class
Mechanism of Late Binding
(iii) Inline function
C++ inline function is powerful concept that is
commonly used with classes. If a function is inline, the compiler places a copy
of the code of that function at each point where the function is called at
compile time.
Any change to an inline function could require all clients of the
function to be recompiled because compiler would need to replace all the code
once again otherwise it will continue with old functionality.
To inline a function, place the keyword inline before the function name and define
the function before any calls are made to the function. The compiler can ignore
the inline qualifier in case defined function is more than a line.
A function definition in a class definition is an inline function
definition, even without the use of the inline specifier.
Following is an example, which makes use of inline function to
return max of two numbers:
#include <iostream>
using namespace std;
inline int Max(int x, int y) {
return (x > y)? x : y;
}
// Main function for the program
int main( ) {
cout << "Max (20,10): " << Max(20,10) << endl;
cout << "Max (0,200): " << Max(0,200) << endl;
cout << "Max (100,1010): " << Max(100,1010) << endl;
return 0;
}
When the above code is compiled and executed, it produces the
following result:
Max (20,10): 20Max (0,200): 200
Max (100,1010): 1010
Q.3.
A.3.
(a) What is concept of reusability? How it is achieved in C++?
Explain with the help of an example.
C++ strongly
supports the concept of reusability. The C++ classes can be reused in several
ways. 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. The mechanism of deriving
a new class from an old one is called inheritance. The old class is referred to
as the base class and the new one is called the derived class or subclass. A
derived class includes all features of the generic base class and then adds
qualities specific to the derived class.
Essential properties of reusable code:
- It is easy to find and to
understand
- There is a reasonable
assurance that it is correct
- It requires no separation
from any containing code
- It requires no changes to be
used in a new program
Myths of reuse:
- Reuse will resolve the
software crisis.
- All code should be reusable.
- Reusing code is always
preferable to coding from scratch.
- Object-oriented languages
make writing reusable code easy.
Nontechnical obstacles:
- The author of Widget must have suspected that a
reusable version of Widget would be useful.
- The author of Widget must have expected to be
rewarded for writing Widget reusably and making it
available.
- Someone must maintain Widget.
- The eventual user of Widget must suspect that Widget exists and must be able to
find it.
- The eventual user of Widget must be able to obtain Widget.
- There must be no legal
obstacles to reuse of Widget.
- The user of Widget must be rewarded for reusing Widget.
Technical obstacles:
- Reusable code must work in
many contexts.
- We almost never know all the
contexts.
- User requirements often
conflict.
- We cannot provide everything
everyone wants.
- The contexts change.
#include<iostream.h>
#include<conio.h>
Class pixeles
{
public:
int c;
void sum(int x, int y)
{
c=x+y;
cout<<"PIXELES CLASSES FOR BCA & MCA \n
RESULT="<<c;
}
};
Class pixelesindia: public pixels
{
public:
int p;
void add(int x, int y)
{
p=x+y;
cout<<"\n www.pixelesindia.com \n RESULT="<<p;
}
};
void main()
{
clrscr();
pixelesindia pc;
pc.sum(4,34);
pc.add(3,3);
getch();
}
(b) Write a C++ program to overload „+‟ operator to find the sum of two complex numbers.
Operator Overloading is a
technique of polymorphism by which an operator(+,- etc) can be used to do
different types of operations. eg:+ can be used to add two integers say a and b
using sum=a+b similarly two floating point numbers say fa,fb by fs=fa+fb. In
this example +,-,*,- operators are overloaded to add,subtract, multiply and
divide two complex numbers. First a class named complex is created which has
overloaded operators like + specified by a function 'complex operator +(complex
c2)' which can used to add two complex numbers like c3=c1+c2 where c1,c2 and c3
are complex numbers.The complete source in C++ to implement operator
overloading is provided below
#include<iostream.h>
#include<conio.h>
class complex
{
int a,b;
public:
void read()
{
cout<<"\n\nEnter the REAL PART :
";
cin>>a;
cout<<"\n\nEnter the IMAGINARY PART
: ";
cin>>b;
}
complex operator +(complex c2)
{
complex c3;
c3.a=a+c2.a;
c3.b=b+c2.b;
return c3;
}
complex operator -(complex c2)
{
complex c3;
c3.a=a-c2.a;
c3.b=b-c2.b;
return c3;
}
complex operator *(complex c2)
{
complex c3;
c3.a=(a*c2.a)-(b*c2.b);
c3.b=(b*c2.a)+(a*c2.b);
return c3;
}
complex operator /(complex c2)
{
complex c3;
c3.a=((a*c2.a)+(b*c2.b))/((c2.a*c2.a)+(c2.b*c2.b));
c3.b=((b*c2.a)-(a*c2.b))/((c2.a*c2.a)+(c2.b*c2.b));
return c3;
}
void display()
{
cout<<a<<"+"<<b<<"i";
}
};
void main()
{
complex c1,c2,c3;
int choice,cont;
do
{
clrscr();
cout<<"\t\tCOMPLEX
NUMBERS\n\n1.ADDITION\n\n2.SUBTRACTION\n\n3.MULTIPLICATION\n\n4.DIVISION";
cout<<"\n\nEnter your choice :
";
cin>>choice;
if(choice==1||choice==2||choice==3||choice==4)
{
cout<<"\n\nEnter the First Complex
Number";
c1.read();
cout<<"\n\nEnter the Second Complex
Number";
c2.read();
}
switch(choice)
{
case 1
: c3=c1+c2;
cout<<"\n\nSUM =
";
c3.display();
break;
case 2
: c3=c1-c2;
cout<<"\n\nResult =
";
c3.display();
break;
case 3 : c3=c1*c2;
cout<<"\n\nPRODUCT =
";
c3.display();
break;
case 4
: c3=c1/c2;
cout<<"\n\nQOUTIENT =
";
c3.display();
break;
default
: cout<<"\n\nUndefined Choice";
}
cout<<"\n\nDo You Want to
Continue?(1-Y,0-N)";
cin>>cont;
}while(cont==1);
getch();
}
#include<iostream.h>
#include<conio.h>
class complex
{
int a,b;
public:
void read()
{
cout<<"\n\nEnter the REAL PART :
";
cin>>a;
cout<<"\n\nEnter the IMAGINARY PART
: ";
cin>>b;
}
complex operator +(complex c2)
{
complex c3;
c3.a=a+c2.a;
c3.b=b+c2.b;
return c3;
}
complex operator -(complex c2)
{
complex c3;
c3.a=a-c2.a;
c3.b=b-c2.b;
return c3;
}
complex operator *(complex c2)
{
complex c3;
c3.a=(a*c2.a)-(b*c2.b);
c3.b=(b*c2.a)+(a*c2.b);
return c3;
}
complex operator /(complex c2)
{
complex c3;
c3.a=((a*c2.a)+(b*c2.b))/((c2.a*c2.a)+(c2.b*c2.b));
c3.b=((b*c2.a)-(a*c2.b))/((c2.a*c2.a)+(c2.b*c2.b));
return c3;
}
void display()
{
cout<<a<<"+"<<b<<"i";
}
};
void main()
{
complex c1,c2,c3;
int choice,cont;
do
{
clrscr();
cout<<"\t\tCOMPLEX
NUMBERS\n\n1.ADDITION\n\n2.SUBTRACTION\n\n3.MULTIPLICATION\n\n4.DIVISION";
cout<<"\n\nEnter your choice :
";
cin>>choice;
if(choice==1||choice==2||choice==3||choice==4)
{
cout<<"\n\nEnter the First Complex
Number";
c1.read();
cout<<"\n\nEnter the Second Complex
Number";
c2.read();
}
switch(choice)
{
case 1
: c3=c1+c2;
cout<<"\n\nSUM =
";
c3.display();
break;
case 2
: c3=c1-c2;
cout<<"\n\nResult =
";
c3.display();
break;
case 3 : c3=c1*c2;
cout<<"\n\nPRODUCT =
";
c3.display();
break;
case 4
: c3=c1/c2;
cout<<"\n\nQOUTIENT =
";
c3.display();
break;
default
: cout<<"\n\nUndefined Choice";
}
cout<<"\n\nDo You Want to
Continue?(1-Y,0-N)";
cin>>cont;
}while(cont==1);
getch();
}
(c) Explain different visibility modes in C++, in context of inheritance
Overview of Inheritance
Inheritance is the capability of one class to acquire properties
and characteristics from another class. The class whose properties are
inherited by other class is called the Parent or Base or Super class. And, the class which inherits
properties of other class is called Child or Derived or Sub class.
Inheritance makes the code reusable. When we inherit an existing
class, all its methods and fields become available in the new class, hence code
is reused.
NOTE : All
members of a class except Private, are inherited
Purpose of Inheritance
1.
Code Reusability
2.
Method Overriding (Hence, Runtime Polymorphism.)
3.
Use of Virtual Keyword
Basic Syntax of Inheritance
class Subclass_name : access_mode Superclass_name
While defining a subclass like this, the super class must be
already defined or atleast declared before the subclass declaration.
Access Mode is used to specify, the mode in which the properties
of superclass will be inherited into subclass, public, privtate or protected.
Example of Inheritance
{ public:
int legs = 4;
};
class Dog : public Animal
{ public:
int tail = 1;
};
int main()
{
Dog d;
cout << d.legs;
cout << d.tail;
}
Output : 4 1
Inheritance Visibility Mode
Depending on Access modifier used while inheritance, the
availability of class members of Super class in the sub class changes. It can
either be private, protected or public.
1) Public Inheritance
This is the most used inheritance mode. In this the protected
member of super class becomes protected members of sub class and public becomes
public.
class Subclass : public Superclass
2) Private Inheritance
In private mode, the protected and public members of super class
become private members of derived class.
class Subclass : Superclass // By default its private inheritance
3) Protected Inheritance
In protected mode, the public and protected members of Super class becomes protected members of Sub class. class subclass : protected Superclass
Table showing all the Visibility Modes
Derived
Class
|
Derived
Class
|
Derived
Class
|
|
Base
class
|
Public
Mode
|
Private
Mode
|
Protected
Mode
|
Private
|
Not
Inherited
|
Not
Inherited
|
Not
Inherited
|
Protected
|
Protected
|
Private
|
Protected
|
Public
|
Public
|
Private
|
Protected
|
Q.4.
A.4
(a) What is function overloading? Explain how overloaded
functions are called with the help of an example.
C++ allows you to specify more than one definition for a function name or an operator in the same scope, which is called function overloading and operator overloading respectively. An overloaded declaration is a declaration that had been declared with the same name as a previously declared declaration in the same scope, except that both declarations have different arguments and obviously different definition (implementation).
When you call an overloaded function or operator, the compiler determines the most appropriate definition to use by comparing the argument types you used to call the function or operator with the parameter types specified in the definitions. The process of selecting the most appropriate overloaded function or operator is called overload resolution.
Function overloading in C++
You can have multiple definitions for the same function name in the same scope. The definition of the function must differ from each other by the types and/or the number of arguments in the argument list. You can not overload function declarations that differ only by return type.
Following is the example where same function print() is being used to print different data types:
#include <iostream>
using namespace std;
class printData {
public:
void print(int i) {
cout << "Printing int: " << i << endl;
}
void print(double f) {
cout << "Printing float: " << f << endl;
}
void print(char* c) {
cout << "Printing character: " << c << endl;
}
};
int main(void) {
printData pd;
// Call print to print integer
pd.print(5);
// Call print to print float
pd.print(500.263);
// Call print to print character
pd.print("Hello C++");
return 0;
}
When the above code is compiled and executed, it produces the following result:
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
Operators overloading in C++
You can redefine or overload most of the built-in operators available in C++. Thus a programmer can use operators with user-defined types as well.
Overloaded operators are functions with special names the keyword operator followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.
Box operator+(const Box&);
declares the addition operator that can be used to add two Box objects and returns final Box object. Most overloaded operators may be defined as ordinary non-member functions or as class member functions. In case we define above function as non-member function of a class then we would have to pass two arguments for each operand as follows:
Box operator+(const Box&, const Box&);
Following is the example to show the concept of operator over loading using a member function. Here an object is passed as an argument whose properties will be accessed using this object, the object which will call this operator can be accessed using this operator as explained below:
#include <iostream>
using namespace std;
class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
void setLength( double len ) {
length = len;
}
void setBreadth( double bre ) {
breadth = bre;
}
void setHeight( double hei ) {
height = hei;
}
// Overload + operator to add two Box objects.
Box operator+(const Box& b) {
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
// Main function for the program
int main( ) {
Box Box1; // Declare Box1 of type Box
Box Box2; // Declare Box2 of type Box
Box Box3; // Declare Box3 of type Box
double volume = 0.0; // Store the volume of a box here
// box 1 specification
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// box 2 specification
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// volume of box 1
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// volume of box 2
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
// Add two object as follows:
Box3 = Box1 + Box2;
// volume of box 3
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
When the above code is compiled and executed, it produces the following result:
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
(b) What is dynamic binding? Explain with the help of an example.
In OOPs Dynamic Binding refers to linking a procedure call to the code that will be executed only at run time. The code associated with the procedure in not known until the program is executed, which is also known as late binding.
Example :
#include <iostream.h>
int Square(int x)
{ return x*x; }
int Cube(int x)
{ return x*x*x; }
int main()
{
int x =10;
int choice;
do
{
cout << "Enter 0 for square value, 1 for cube value: ";
cin >> choice;
} while (choice < 0 || choice > 1);
int (*ptr) (int); switch (choice)
{
case 0: ptr = Square; break;
case 1: ptr = Cube; break;
} cout << "The result is: " << ptr(x) << endl;
return 0; }
Result :
Enter 0 for square value, 1 for cube value:0
The result is:100
Example :
#include <iostream.h>
int Square(int x)
{ return x*x; }
int Cube(int x)
{ return x*x*x; }
int main()
{
int x =10;
int choice;
do
{
cout << "Enter 0 for square value, 1 for cube value: ";
cin >> choice;
} while (choice < 0 || choice > 1);
int (*ptr) (int); switch (choice)
{
case 0: ptr = Square; break;
case 1: ptr = Cube; break;
} cout << "The result is: " << ptr(x) << endl;
return 0; }
Result :
Enter 0 for square value, 1 for cube value:0
The result is:100
(c) What is an abstract class? Explain with an example. Also
explain features of an abstract class.
Abstract Class
Abstract Class is a class which contains atleast one Pure Virtual function in it. Abstract classes are used to provide an Interface for its sub classes. Classes inheriting an Abstract Class must provide definition to the pure virtual function, otherwise they will also become abstract class.
Characteristics of Abstract Class
1. Abstract class cannot be instantiated, but pointers and refrences of Abstract class type can be created.
2. Abstract class can have normal functions and variables along with a pure virtual function.
3. Abstract classes are mainly used for Upcasting, so that its derived classes can use its interface.
4. Classes inheriting an Abstract Class must implement all pure virtual functions, or else they will become Abstract too.
Pure Virtual Functions
Pure virtual Functions are virtual functions with no definition. They start with virtual keyword and ends with = 0. Here is the syntax for a pure virtual function, virtual void f() = 0;
Example of Abstract Class
class Base //Abstract base class
{
public:
virtual void show() = 0; //Pure Virtual Function
};
class Derived:public Base
{
public:
void show()
{ cout << "Implementation of Virtual Function in Derived class"; }
};
int main()
{
Base obj; //Compile Time Error
Base *b;
Derived d;
b = &d;
b->show();
}
Output : Implementation of Virtual Function in Derived class
In the above example Base class is abstract, with pure virtual show() function, hence we cannot create object of base class.
Why can't we create Object of Abstract Class ?
When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so.
Pure Virtual definitions
· Pure Virtual functions can be given a small definition in the Abstract class, which you want all the derived classes to have. Still you cannot create object of Abstract class.
· Also, the Pure Virtual function must be defined outside the class definition. If you will define it inside the class definition, complier will give an error. Inline pure virtual definition is Illegal. class Base //Abstract base class
{
public:
virtual void show() = 0; //Pure Virtual Function
};
void Base :: show() //Pure Virtual definition
{
cout << "Pure Virtual definition\n";
}
class Derived:public Base
{
public:
void show()
{ cout << "Implementation of Virtual Function in Derived class"; }
};
int main()
{
Base *b;
Derived d;
b = &d;
b->show();
}
Output : Pure Virtual definition
Implementation of Virtual Function in Derived class
Abstract Class is a class which contains atleast one Pure Virtual function in it. Abstract classes are used to provide an Interface for its sub classes. Classes inheriting an Abstract Class must provide definition to the pure virtual function, otherwise they will also become abstract class.
Characteristics of Abstract Class
1. Abstract class cannot be instantiated, but pointers and refrences of Abstract class type can be created.
2. Abstract class can have normal functions and variables along with a pure virtual function.
3. Abstract classes are mainly used for Upcasting, so that its derived classes can use its interface.
4. Classes inheriting an Abstract Class must implement all pure virtual functions, or else they will become Abstract too.
Pure Virtual Functions
Pure virtual Functions are virtual functions with no definition. They start with virtual keyword and ends with = 0. Here is the syntax for a pure virtual function, virtual void f() = 0;
Example of Abstract Class
class Base //Abstract base class
{
public:
virtual void show() = 0; //Pure Virtual Function
};
class Derived:public Base
{
public:
void show()
{ cout << "Implementation of Virtual Function in Derived class"; }
};
int main()
{
Base obj; //Compile Time Error
Base *b;
Derived d;
b = &d;
b->show();
}
Output : Implementation of Virtual Function in Derived class
In the above example Base class is abstract, with pure virtual show() function, hence we cannot create object of base class.
Why can't we create Object of Abstract Class ?
When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so.
Pure Virtual definitions
· Pure Virtual functions can be given a small definition in the Abstract class, which you want all the derived classes to have. Still you cannot create object of Abstract class.
· Also, the Pure Virtual function must be defined outside the class definition. If you will define it inside the class definition, complier will give an error. Inline pure virtual definition is Illegal. class Base //Abstract base class
{
public:
virtual void show() = 0; //Pure Virtual Function
};
void Base :: show() //Pure Virtual definition
{
cout << "Pure Virtual definition\n";
}
class Derived:public Base
{
public:
void show()
{ cout << "Implementation of Virtual Function in Derived class"; }
};
int main()
{
Base *b;
Derived d;
b = &d;
b->show();
}
Output : Pure Virtual definition
Implementation of Virtual Function in Derived class
Q.5.
A.5.
(a) What is template? Write appropriate statements to create a
template class for Stack data structure in C++.
Templates are the foundation of generic programming, which involves writing code in a way that is independent of any particular type. A template is a blueprint or formula for creating a generic class or a function. The library containers like iterators and algorithms are examples of generic programming and have been developed using template concept.
There is a single definition of each container, such as vector, but we can define many different kinds of vectors for example, vector <int> or vector <string>.
You can use templates to define functions as well as classes, let us see how do they work:
Function Template
The general form of a template function definition is shown here:
template <class type> ret-type func-name(parameter list) {
// body of function
}
Here, type is a placeholder name for a data type used by the function. This name can be used within the function definition.
The following is the example of a function template that returns the maximum of two values:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b) {
return a < b ? b:a;
}
int main () {
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
If we compile and run above code, this would produce the following result:
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World
Class Template
Just as we can define function templates, we can also define class templates. The general form of a generic class declaration is shown here:
template <class type> class class-name {
.
.
.
}
Here, type is the placeholder type name, which will be specified when a class is instantiated. You can define more than one generic data type by using a comma-separated list.
Following is the example to define class Stack<> and implement generic methods to push and pop the elements from the stack:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems; // elements
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const{ // return true if empty.
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem) {
// append copy of passed element
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop () {
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// remove last element
elems.pop_back();
}
template <class T>
T Stack<T>::top () const {
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// return copy of last element
return elems.back();
}
int main() {
try {
Stack<int> intStack; // stack of ints
Stack<string> stringStack; // stack of strings
// manipulate int stack
intStack.push(7);
cout << intStack.top() <<endl;
// manipulate string stack
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
If we compile and run above code, this would produce the following result:
7
hello
Exception: Stack<>::pop(): empty stack
(b) What are containers? Explain use of List container class with the help of an example.
A container stores many entities and provide sequential or direct access to them. List, vector and strings are such containers in standard template library. The string class is a container that holds chars. All container classes access the contained elements safely and efficiently by using iterators. Container class is a class that hold group of same or mixed objects in memory. It can be heterogeneous and homogeneous. Heterogeneous container class can hold mixed objects in memory whereas when it is holding same objects, it is called as homogeneous container class.
A class is said to be a container class which is utilized for the purpose of holding objects in memory or persistent media. A generic class plays a role of generic holder. A container class is a good blend of predefined behavior and an interface that is well known. The purpose of container class is to hide the topology for the purpose of objects list maintenance in memory. A container class is known as heterogeneous container, when it contains a set of different objects. A container class is known as homogeneous container when it contains a set of similar objects.
What is container class? Explain containers of pointer.
- Container class is one of the classes that were put into class libraries. To handle objects that contain other objects, container classes are used. A GUI class library contains a group of container classes.
- Containers of pointers provide containers to hold the objects that are heap-allocated in manner that is exception-safe and with minimum overhead. The central idea is to make OOP easier in C++. This is done by establishing a standard a set of classes, methods to deal with OO specific problems.
What are the C++ standardized container classes?
The following are the standardized container classes :
1. std::map :
Used for handle sparse array or a sparse matrix.
2. std::vector :
Like an array, this standard container class offers additional features such as bunds checking through the at () member function, inserting or removing elements, automatic memory management and throwing exceptions.
std::string :
A better supplement for arrays of chars.
(c) What is exception handling? Write C++ program to
demonstrate exception handling with multiple catch
statements.
An exception is a problem that arises during the execution of a program. A C++ exception is a response to an exceptional circumstance that arises while a program is running, such as an attempt to divide by zero.
Exceptions provide a way to transfer control from one part of a program to another. C++ exception handling is built upon three keywords: try, catch, and throw.
· throw: A program throws an exception when a problem shows up. This is done using a throw keyword.
· catch: A program catches an exception with an exception handler at the place in a program where you want to handle the problem. The catch keyword indicates the catching of an exception.
· try: A try block identifies a block of code for which particular exceptions will be activated. It's followed by one or more catch blocks.
Assuming a block will raise an exception, a method catches an exception using a combination of the try and catch keywords. A try/catch block is placed around the code that might generate an exception. Code within a try/catch block is referred to as protected code, and the syntax for using try/catch looks like the following:
try
{
// protected code
}catch( ExceptionName e1 )
{
// catch block
}catch( ExceptionName e2 )
{
// catch block
}catch( ExceptionName eN )
{
// catch block
}
You can list down multiple catch statements to catch different type of exceptions in case your try block raises more than one exception in different situations.
Throwing Exceptions
Exceptions can be thrown anywhere within a code block using throw statements. The operand of the throw statements determines a type for the exception and can be any expression and the type of the result of the expression determines the type of exception thrown.
Following is an example of throwing an exception when dividing by zero condition occurs:
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
Catching Exceptions
The catch block following the try block catches any exception. You can specify what type of exception you want to catch and this is determined by the exception declaration that appears in parentheses following the keyword catch.
try {
// protected code
}catch( ExceptionName e ) {
// code to handle ExceptionName exception
}
Above code will catch an exception of ExceptionName type. If you want to specify that a catch block should handle any type of exception that is thrown in a try block, you must put an ellipsis, ..., between the parentheses enclosing the exception declaration as follows:
try {
// protected code
}catch(...) {
// code to handle any exception
}
The following is an example, which throws a division by zero exception and we catch it in catch block.
#include <iostream>
using namespace std;
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
int main () {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
Because we are raising an exception of type const char*, so while catching this exception, we have to use const char* in catch block. If we compile and run above code, this would produce the following result:
Division by zero condition!
No comments:
Post a Comment