Object Oriented Programming in C++
Q1: Short
answer type:
1.
Justify
the need of scope resolution operator.
Ans:-There are two uses of the scope resolution operator in C++.
The first use being that a scope resolution operator is used to unhide the global variable that might have got hidden by the local variables. Hence in order to access the hidden global variable one needs to prefix the variable name with the scope resolution operator (::).
e.g.
int i = 10;
int main ()
{
int i = 20;
cout << i; // this prints the value 20
cout << ::i; // in order to use the global i one needs to prefix it with the scope resolution operator.
}
The second use of the operator is used to access the members declared in class scope. Whenever a scope resolution operator is used the name of the member that follows the operator is looked up in the scope of the class with the name that appears before the operator.
The scope resolution operator (::) in C++ is used to define the already declared member functions (in the header file with the .hpp or the .h extension) of a particular class. In the .cpp file one can define the usual global functions or the member functions of the class. To differentiate between the normal functions and the member functions of the class, one needs to use the scope resolution operator (::) in between the class name and the member function name i.e. ship::foo() where ship is a class and foo() is a member function of the class ship.
The first use being that a scope resolution operator is used to unhide the global variable that might have got hidden by the local variables. Hence in order to access the hidden global variable one needs to prefix the variable name with the scope resolution operator (::).
e.g.
int i = 10;
int main ()
{
int i = 20;
cout << i; // this prints the value 20
cout << ::i; // in order to use the global i one needs to prefix it with the scope resolution operator.
}
The second use of the operator is used to access the members declared in class scope. Whenever a scope resolution operator is used the name of the member that follows the operator is looked up in the scope of the class with the name that appears before the operator.
The scope resolution operator (::) in C++ is used to define the already declared member functions (in the header file with the .hpp or the .h extension) of a particular class. In the .cpp file one can define the usual global functions or the member functions of the class. To differentiate between the normal functions and the member functions of the class, one needs to use the scope resolution operator (::) in between the class name and the member function name i.e. ship::foo() where ship is a class and foo() is a member function of the class ship.
The other uses of the resolution operator is to resolve the scope of a
variable when the same identifier is used to represent a global variable, a
local variable, and members of one or more class(es). If the resolution
operator is placed between the class name and the data member belonging to the
class then the data name belonging to the particular class is referenced. If
the resolution operator is placed in front of the variable name then the global
variable is referenced.
When no resolution operator is placed then the local
variable is referenced.
a)
What
is a class and objects? Define.
Ans:
- A class is the collection of related
data and function under a single name. A C++ program can have any number of
classes. When related data and functions are kept under a class, it helps to
visualize the complex problem efficiently and effectively.
When a class is defined, no memory is allocated. You can
imagine like a datatype.
int
var;
The above code specifies var is
a variable of type integer; int is used for specifying variable var is
of integer type. Similarly, classes are also just the specification for objects
and object bears the property of that class.
b)
What
is the purpose of operator function?
Ans: - An overloaded operator is called an operator function. You declare an
operator function with the keyword operator
preceding the operator. Overloaded operators are distinct from overloaded
functions, but like overloaded functions, they are distinguished by the number
and types of operands used with the operator.
c)
What
is friend function?
Ans: - A friend function of a class is defined outside
that class' scope but it has the right to access all private and protected
members of the class. Even though the prototypes for friend functions appear in
the class definition, friends are not member functions.
A friend can be a function, function template, or member
function, or a class or class template, in which case the entire class and all
of its members are friends.
d)
What
is the use of this pointer?
Ans:- Every object in C++ has access to its own address
through an important pointer called this pointer. The this
pointer is an implicit parameter to all member functions. Therefore, inside a
member function, this may be used to refer to the invoking object.
Friend functions do not have a this pointer,
because friends are not members of a class. Only member functions have a this
pointer.
e)
How exception handling is beneficial for object
oriented programming?
Ans: - Benefits
are: - Exceptions allow you to organize your *ahem* exception handling much
better and just because exceptions are supposed to be exceptions to the rule
they won't occur much. Use them wherever appropriate; don't use them as an
alternative return mechanism.
Handle exceptions as close to where they were thrown; don't handle exceptions you can't really handle and never ever muffle exceptions away without a darn good reason.
On the other hand: throw a most specific exception, i.e. help your caller to find
out what exactly went wrong, i.e. don't just yell "error!" when you can do better.
Handle exceptions as close to where they were thrown; don't handle exceptions you can't really handle and never ever muffle exceptions away without a darn good reason.
On the other hand: throw a most specific exception, i.e. help your caller to find
out what exactly went wrong, i.e. don't just yell "error!" when you can do better.
f)
What are the advantages of container?
Ans: - A container class is a class that is used to hold
objects in memory or external storage. A container class acts as a generic
holder. A container class has a predefined behavior and a well-known interface.
A container class is a supporting class
whose purpose is to hide the topology used for maintaining the list of objects
in memory. When a container class contains a group of mixed objects, the
container is called a container; when the container is holding a group of
objects that are all the same, the container is called a homogeneous container.
g)
List 5 object oriented languages.
Ans: - C++ , Java, Csharp, python, perl
h)
Explain the concept of streams in C++?
Ans: - Streams in here means the flow
of data.
Flow and output flow two common kinds of input flows are from input devices (keyboard,mouse) or Files means reading or receiving of data from a source. first case source is a input device, in second case source is a File.
Flow and output flow two common kinds of input flows are from input devices (keyboard,mouse) or Files means reading or receiving of data from a source. first case source is a input device, in second case source is a File.
Similarly for output stream. Output
devices and Files.
Destination of data (Or where the data should be printed ) . Output Devices ( Screen, Printer ) or Files
So, in C++ there are header files to handle these streams
istream.h (input stream)
ostream.h (outputstream)
iostream.h ( coombination of istreanm&ostream)
The above are for input/output devices
Similarly for files
ifstream (input files)
ifstream(output files)
fstream.h ( combination of both ifstream and fstream)
Destination of data (Or where the data should be printed ) . Output Devices ( Screen, Printer ) or Files
So, in C++ there are header files to handle these streams
istream.h (input stream)
ostream.h (outputstream)
iostream.h ( coombination of istreanm&ostream)
The above are for input/output devices
Similarly for files
ifstream (input files)
ifstream(output files)
fstream.h ( combination of both ifstream and fstream)
i)
How data and functions are are organized in an object
oriented approach?
Ans:- Objects = Data + Function
One of the key concepts behind so-called object-oriented programming
(OOP) is the notion of an object. An object
is a new kind of value that can, as a first cut, be understood as a pairing
together of two familiar concepts: data and function.
·
An object is like a structure in that it
has a fixed number of fields, thus an object (again, like a structure) can
represent compound data. But unlike a structure, an object contains not just data, but
functionality too;
·
An object is like a (set of) function(s) in
that it has behavior—it computes; it is not just inert data.
Q2: Explain function overloading and
give suitable example. How it is different from operator overloading?
Ans:
- 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 cannot 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("This is 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: This is C++.
Operators
overloading in C++:
One of the nice features of C++ is
that you can give special meanings to operators, when they are used with
user-defined classes. This is called operator overloading. You can
implement C++ operator overloads by providing special member-functions on your
classes that follow a particular naming convention. For example, to overload
the + operator for your class, you would provide a
member-function named operator+ on your class.
The following set of operators is
commonly overloaded for user-defined classes:
- =
(assignment operator)
- + - * (binary arithmetic operators)
- += -= *= (compound assignment operators)
- == != (comparison operators)
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
Q3:- Explain polymorphism and give one
suitable example to illustrate the concept? (10)
Ans:
- One of the key features of class
inheritance is that a pointer to a derived class is type-compatible with a
pointer to its base class. Polymorphism is the art of taking advantage of this
simple but powerful and versatile feature.
"Poly"
means "many" and "morph" means "form". Polymorphism is the ability of an object (or reference) to
assume (be replaced by) or become many different forms of object.
Example: function overloading, function overriding, virtual functions. Another
example can be a plus ‘+’ sign, used for adding two integers or for using it to
concatenate two strings.
In programming languages, polymorphism
means that some code or operations or objects behave differently in different
contexts.
For example, the +
(plus) operator in C++:
4
+ 5 <-- integer addition
3.14
+ 2.0 <-- floating point addition
s1
+ "bar" <-- string
concatenation!
In C++, that type of polymorphism is
called overloading.
Typically, when the term polymorphism
is used with C++, however, it refers to using virtual methods,
which we'll discuss shortly.
· Employee
example:
Here, we will represent 2 types of
employees as classes in C++:
- a generic employee (class Employee)
- a manager (class Manager)
For these employees, we'll store data,
like their:
- name
- pay rate
- initialize the employee
- get the employee's fields
- calculate the employee's pay
Types of Polymorphism:-
Compile
time polymorphism:
In this method object is
bound to the function call at the compile time itself.
- Run time polymorphism:
Example:-
#include <iostream.h>
class Value
{
protected:
int val;
public:
void set_values
(int a)
{ val=a;}
};
class Cube: public Value
{
public:
int cube()
{ return (val*val*val);
}
};
int main () {
Cube cb;
Value * ptr =
&cb;
ptr->set_values
(10);
cout <<
"The cube of 10 is::" << cb.cube() << endl;
return 0;
}
Result:
The cube of 10 is:
1000
In the above OOPs example "Cube" is a derived class
of "Value". To implement polymorphism a pointer "ptr" is
used to reference to the members of the class "Cube". This is an
example for "Compile time polymorphism."
Q4:- Explain
the concept of Exception handling in C++. (10)
Ans:- 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:
Syntax:-
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.
Example: function overloading, function overriding, virtual functions. Another example can be a plus ‘+’ sign, used for adding two integers or for using it to concatenate two strings.
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!
Q5:- What are constructors and
destructors in C++? Explain the constructors function and destructor with
example? (10)
Ans: - A
class constructor is a special member function of a
class that is executed whenever we create new objects of that class.
A constructor will have exact same name as the class and it
does not have any return type at all, not even void. Constructors can be very
useful for setting initial values for certain member variables.
Because classes have
complicated internal structures, including data and functions, object
initialization and cleanup for classes is much more complicated than it is for
simple data structures. Constructors and destructors are special member
functions of classes that are used to construct and destroy class objects.
Construction may involve memory allocation and initialization for objects.
Destruction may involve cleanup and de-allocation of memory for objects.
Like other member
functions, constructors and destructors are declared within a class
declaration. They can be defined inline or external to the class declaration.
Constructors can have default arguments. Unlike other member functions,
constructors can have member initialization lists. The following restrictions
apply to constructors and destructors:
- Constructors and destructors do not have return types
nor can they return values.
- References and pointers cannot be used on constructors
and destructors because their addresses cannot be taken.
- Constructors cannot be declared with the
keyword virtual.
- Constructors and destructors cannot be
declared static, const, or volatile.
- Unions cannot contain class objects that have
constructors or destructors.
Constructors and
destructors obey the same access rules as member functions. For example, if you
declare a constructor with protected access, only derived classes and friends
can use it to create class objects.
The compiler
automatically calls constructors when defining class objects and calls
destructors when class objects go out of scope. A constructor does not allocate
memory for the class object it’s this pointer refers to, but may
allocate storage for more objects than its class object refers to. If memory
allocation is required for objects, constructors can explicitly call
the new operator. During cleanup, a destructor may release objects
allocated by the corresponding constructor. To release objects, use
the delete operator.
Derived classes do not
inherit or overload constructors or destructors from their base classes, but
they do call the constructor and destructor of base classes. Destructors can be
declared with the keyword virtual.
Constructors are also
called when local or temporary class objects are created, and destructors are
called when local or temporary objects go out of scope.
Destructors syntax:
When an object is no
longer needed it has to be deleted. Objects created within functions as local
variables, i.e. using the form:-
Track MyTrack;
are deleted
automatically, once control leaves the innermost compound statement (
i.e. the innermost {..}) that contains the statement. For objects created
dynamically:-
Track *MyTrackPtr = new Track;
the object remains until
explicitly deleted, although, in the above statement, the pointer MyTrack
is a local and will get deleted automatically. To delete a single object
the delete operator
is applied to a pointer to it:-
delete MyTrack;
To delete an array:-
delete [] MyTracks;
note that the array [] really is empty - the compiler takes
care to record the array size.
Following example
explains the concept of constructor:
#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
Q6:- What are templates in C++? Explain
with programs the function templates and class templates. (10)
Ans: - 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:
Syntax:-
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:
Syntax:-
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
Q8: Write
short notes on (any two) :- (10)
1.
Virtual Functions
2.
Standard Template library
3.
Abstract classes
4.
Manipulators
Ans: - 1.) Virtual Functions:-
The concept of the virtual function
solves the following problem:
In object-oriented programming when
a derived class inherits from a base class, an object of the derived class may
be referred to via a pointer or reference of either the base class type or the
derived class type. If there are base class methods overridden by the derived
class, the method actually called by such a reference or pointer can be bound
either 'early' (by the compiler), according to the declared type of the pointer
or reference, or 'late' (i.e. by the runtime system of the language), according
to the actual type of the object referred to.
Virtual functions are resolved
'late'. If the function in question is 'virtual' in the base class, the
most-derived class's implementation of the function is called according to the
actual type of the object referred to, regardless of the declared type of the
pointer or reference. If it is not 'virtual', the method is resolved 'early'
and the function called is selected according to the declared type of the
pointer or reference.
Virtual functions allow a program
to call methods that don't necessarily even exist at the moment the code is
compiled.
In C++, virtual methods are
declared by prepending the virtual keyword to the
function's declaration in the base class. This modifier is inherited by all
implementations of that method in derived classes, meaning that they can
continue to over-ride each other and be late-bound.
For example, a base class Animal could have a virtual function eat.
Subclass Fish would implement eat() differently than subclass Wolf,
but one can invoke eat() on any class instance referred to as Animal, and get the eat()
behavior of the specific subclass.
class Animal
{
void /*nonvirtual*/ move() {
cout << "This animal moves in some
way" << endl;
}
virtual void eat() {}
};
// The class "Animal" may possess a declaration for eat() if desired.
class Llama : public Animal
{
// The non virtual function move() is inherited but cannot be
overridden
void eat() {
cout << "Llamas eat grass!"
<< endl;
}
};
{
void /*nonvirtual*/ move() {
cout << "This animal moves in some way" << endl;
}
virtual void eat() {}
};
// The class "Animal" may possess a declaration for eat() if desired.
class Llama : public Animal
{
// The non virtual function move() is inherited but cannot be overridden
void eat() {
cout << "Llamas eat grass!" << endl;
}
};
2.) Standard Template Library
The Standard Template Library, or STL,
is a C++ library of container classes, algorithms, and iterators; it provides
many of the basic algorithms and data structures of computer science. The STL
is a generic library, meaning that its components are heavily
parameterized: almost every component in the STL is a template. You should make
sure that you understand how templates work in C++ before you use the STL.
A standard template library uses
templates to achieve the required results, and provides compile time
polymorphism. STLs also include components such as functors, iterators and
algorithm containers.
An STL includes sequence and
associative containers. Standard sequence containers include deque, vector and
list, while standard associative containers are multiset, map, multimap and
set. Container adapters such as queue and stack are also containers with
specific interfaces, which use other containers as implementation.
There are five different types of iterators within STL:
- Input iterators
- Output iterators
- Bidirectional iterators
- Random access iterators
An STL includes algorithms to
perform searching and sorting, each of which is implemented to require a
certain level of iterator. STL also includes classes that overload the function
operator and are called function objects, or functors. These aid in keeping and
retrieving state information in functions passed to other functions.
There are five different types of iterators within STL:
No comments:
Post a Comment