Professional Documents
Culture Documents
Data Structures and Object Oriented Programming in C++ Unit - Ii Advanced Object Oriented Programming
Data Structures and Object Oriented Programming in C++ Unit - Ii Advanced Object Oriented Programming
UNIT – II
2.3. Pointers
A pointer is a variable that is used to store a memory address. The address is the location of the variable in
the memory. Pointers help in allocating memory dynamically. Pointers improve execution time and saves
space. Pointer points to a particular data type. The general form of declaring pointer is:-
type is the base type of the pointer and variable_name is the name of the variable of the pointer. For
example,
Pointer Operators
There are two important pointer operators such as ‘*’ and ‘&’. The ‘&’ is a unary operator. The unary
operator returns the address of the memory where a variable is located. For example,
int c;
x=&c;
variable x is the pointer of the type integer and it points to location of the variable c. When the statement
int p;
x=&c;
p=*x;
variable x is the pointer of integer type. It points to the address of the location of the variable c. The
pointer x will contain the contents of the memory location of variable c. It will contain value 100. When
statement
p=*x;
is executed, ‘*’ operator returns the content of the pointer x and variable p will contain value 100 as the
pointer x contain value 100 at its memory location. Here is a program which illustrates the working of
pointers.
#include<iostream>
int main ()
int p;
x=&c;
p=*x;
cout << " The address of the memory location of x : " << x << endl;
cout << " The contents of the pointer x : " << *x << endl;
cout << " The contents of the variable p : " << p << endl;
return(0);
}
Pointer Arithmetic
There are only two arithmetic operations that can be performed on pointers such as addition and
subtraction. The integer value can be added or subtracted from the pointer. The result of addition and
subtraction is an address. The difference of the two memory addresses results an integer and not the
memory address. When a pointer is incremented it points to the memory location of the next element of its
base type and when it is decremented it points to the memory location of the previous element of the same
base type. For example,
p=x++;
here x and p are pointers of integer type. Pointer x is incremented by 1. Now variable p points to the
memory location next to the memory location of the pointer x. Suppose memory address of x is 2000 and
as a result p will contain memory address 2004 because integer type takes four bytes so the memory
address is incremented by 4. Incrementing the pointer results in incrementing the memory address by the
number of bytes occupied by the base type. For example,
p=x++;
variables x and p are pointers of double type. Pointer x is incremented by 1. Now if the memory address of
x was 2000 and after incrementing p will contain memory address 2008 as double takes 8 bytes.
Decrementing the pointer results in decrementing the memory address by the number of bytes occupied by
the base type. You cannot add two pointers. No multiplication and division can be performed on pointers.
Here is a program which illustrates the working of pointer arithmetic.
#include<iostream>
int main ()
x=&c;
p=x+2;
q=x-2;
cout << "The address of p after incrementing x by 2 : " << p << endl;
cout << "The address of q after derementing x by 2 : " << q << endl;
cout << " The no of elements between p and q :" << a << endl;
return(0);
The pointers and arrays have a very close relationship. The pointer can be set to the address of the first
element of the array. For example,
p=&age;
p will point to the address of the first element of the array. For example
(p+4)
will point to the fifth element of the array. Pointers are helpful where size of the array is unknown.
Declaring the array with a size of large value wastes lot of space. Pointers improve the execution time.
Here is a program which illustrates the working of arrays and pointers.
2.4. Polymorphism
Polymorphism is the ability to take more than one form. An operation may exhibit different behaviors in different.
The behavior depends upon the type of data used.
Types of polymorphism
Function overloading
Operator overloading
Prototypes of base class version of a virtual function and all the derived class versions must be
identical.
If a virtual function is defined in the base class, it need not be redefined in the derived class.
A pure virtual function is a function declared in a base class that has no definition relative to the base class.
In such cases, the compiler requires each derived class to either define the function or re declare it as a pure
virtual function. A class containing pure virtual functions cannot be used to declare any object of its own. It
is also known as “do nothing” function. The “do-nothing” function is defined as follows: virtual void
display ( ) =0;
A pure virtual function is a virtual function that has no definition within the base class. To declare a pure
virtual function, use this general form:
virtual type func-name(parameter-list) = 0;
Example Program
#include <iostream>
class number
{
protected:
int val;
public:
void setval(int i) { val = i; }
// show() is a pure virtual function
virtual void show() = 0;
};
class hextype : public number
{
public:
void show()
{
cout << hex << val << "\n";
}
};
class dectype : public number
{
public:
void show()
{
cout << val << "\n";
}
};
class octtype : public number
{
public:
void show()
{
cout << oct << val << "\n";
}
};
int main()
{
dectype d;
hextype h;
octtype o;
d.setval(20);
d.show(); // displays 20 - decimal
h.setval(20);
h.show(); // displays 14 - hexadecimal
o.setval(20);
o.show(); // displays 24 - octal
return 0;
}
Abstract Classes
A class that contains at least one pure virtual function is said to be abstract. Because an abstract class
contains one or more functions for which there is no definition (that is, a pure virtual function), no objects
of an abstract class may be created. Instead, an abstract class constitutes an incomplete type that is used as a
foundation for derived classes.
Although you cannot create objects of an abstract class, you can create pointers and references to an
abstract class. This allows abstract classes to support run-time polymorphism, which relies upon base-class
pointers and references to select the proper virtual function.
2.5. File Handling
File. The information / data stored under a specific name on a storage device, is called a file.
Text file. It is a file that stores information in ASCII characters. In text files, each line of text is terminated
with a special character known as EOL (End of Line) character or delimiter character. When this EOL
character is read or written, certain internal translations take place.
Binary file. It is a file that contains information in the same format as it is held in memory. In binary files,
no delimiters are used for a line and no translations occur here.
Opening a file
All these flags can be combined using the bitwise operator OR (|). For example, if we want to open the file
example.bin in binary mode to add data we could do it by the following call to member function open():
fstream file;
file.open ("example.bin", ios::out | ios::app | ios::binary);
CLOSING FILE
fout.close();
fin.close();
All i/o streams objects have, at least, one internal stream pointer:
ifstream, like istream, has a pointer known as the get pointer that points to the element to be read in the next
input operation.
ofstream, like ostream, has a pointer known as the put pointer that points to the location where the next
element has to be written.
Finally, fstream, inherits both, the get and the put pointers, from iostream (which is itself derived from both
istream and ostream).
These internal stream pointers that point to the reading or writing locations within a stream can be
manipulated using the following member functions:
seekg(offset, refposition );
seekp(offset, refposition );
The parameter offset represents the number of bytes the file pointer is to be moved from the location
specified by the parameter refposition. The refposition takes one of the following three constants defined in
the ios class.
example:
file.seekg(-10, ios::cur);
#include<fstream.h>
#include<conio.h>
int main()
{
ifstream fin;
fin.open("out.txt");
char ch;
while(!fin.eof())
{
fin.get(ch);
cout<<ch;
}
fin.close();
getch();
return 0;
}
2.6. Templates
Templates are a feature of the C++ programming language that allows functions and classes to operate with
generic types. This allows a function or class to work on many different data types without being rewritten
for each one.
Types of templates
Function template
Class template
Function template
A function template specifies how an individual function can be constructed. The limitation of such
functions is that they operate only on a particular data type. It can be overcome by defining that function as
a function template or generic function.
Syntax of function template
template<class T,…>
ReturnType FuncName(arguments)
{
}
// Function template example.
#include <iostream>
using namespace std;
// This is a function template.
template <class X> void swapargs(X &a, X &b)
{
X temp;
temp = a;
a = b;
b = temp;
}
int main()
{
int i=10, j=20;
double x=10.1, y=23.3;
char a='x', b='z';
cout << "Original i, j: " << i << ' ' << j << '\n';
cout << "Original x, y: " << x << ' ' << y << '\n';
cout << "Original a, b: " << a << ' ' << b << '\n';
swapargs(i, j); // swap integers
swapargs(x, y); // swap floats
swapargs(a, b); // swap chars
cout << "Swapped i, j: " << i << ' ' << j << '\n';
cout << "Swapped x, y: " << x << ' ' << y << '\n';
cout << "Swapped a, b: " << a << ' ' << b << '\n';
return 0;
}
Class template
Classes can also be declared to operate on different data types. Such classes are called class templates. A
class template specifies how individual classes can be constructed similar to normal class specification
// class templates
#include <iostream>
template <class T>
class mypair
{
T a, b;
public:
mypair (T first, T second)
{
a=first; b=second;
}
T getmax ();
};
template <class T>
T mypair<T>::getmax ()
{
T retval;
retval = a>b? a : b;
return retval;
}
int main ()
{
mypair <int> myobject (100, 75);
cout << myobject.getmax();
return 0;
}
2.7. Exception handling
n exception is a situation that would be unusual for the program that is being processed. As a programmer,
you should anticipate any abnormal behavior that could be caused by the user entering wrong information
that could otherwise lead to unpredictable results.
An error result or an unpredictable behavior on your program not caused by the operating system but that
occurs in your program is called an exception. The ability to deal with a program’s eventual abnormal
behavior is called exception handling. C++ provides three keywords to handle an exception.
1. Trying the normal flow: To deal with the expected behavior of a program, use the try keyword as
in the following syntax:
try {Behavior}
The try keyword is required. It lets the compiler know that you are anticipating an abnormal
behavior and will try to deal with it. The actual behavior that needs to be evaluated is included
between an opening curly bracket “{“ and a closing curly bracket “}”. Inside of the brackets,
implement the normal flow that the program should follow, at least for this section of the code.
2. Catching Errors: During the flow of the program as part of the try section, if an abnormal
behavior occurs, instead of letting the program crash or instead of letting the compiler send the error
to the operating system, you can transfer the flow of the program to another section that can deal
with it.
try {
// Try the program flow
}
catch(Argument)
{
// Catch the exception
}
3. Throwing an error: There are two main ways an abnormal program behavior is transferred from
the try block to the catch clause. This transfer is actually carried by the throw keyword. Unlike the
try and catch blocks, the throw keyword is independent of a formal syntax but still follows some
rules.
Facing an Exception
An exception is a behavior that should not occur in your program but is likely to show up. The
simplest exception looks like a conditional statement and here is an example:
#include <iostream>
int main()
{
int StudentAge;
cout << "Student Age: ";
cin >> StudentAge;
try
{
if(StudentAge < 0)
throw;
cout << "\nStudent Age: " << StudentAge << "\n\n";
}
catch(...)
{
}
cout << "\n";
return 0;
}
The exceptions as we have seen so far dealt with a single exception in a program. Most of the time, a
typical program will throw different types of errors. The C++ language allows you to include
different catch blocks. Each catch block can face a specific error. The syntax used is:
try {
Code to Try
}
catch(Arg1)
{
One Exception
}
catch(Arg2)
{
Another Exception
}
The compiler would proceed in a top-down as follows:
1. Following the normal flow control of the program, the compiler enters the try block.
2. If no exception occurs in the try block, the rest of the try block is executed.
If an exception occurs in the try block, the try displays a throw that specifies the type of error
that happened.
a. The compiler gets out of the try block and examines the first catch
b. If the first catch doesn’t match the thrown error, the compiler proceeds with the next
catch. This continues until the compiler finds a catch that matches the thrown error.
c. If one of the catches matches the thrown error, its body executes. If no catch matches
the thrown error, you have (or the compiler has) two alternatives. If there is no catch
that matches the error (which means that you didn’t provide a matching catch), the
compiler hands the program flow to the operating system (which calls the terminate()
function). Another alternative is to include a catch whose argument is three periods:
catch(…). The catch(…) is used if no other catch, provided there was another,
matches the thrown error. The catch(…), if included as part of a catch clause, must
always be the last catch, unless it is the only catch of the clause.
Multiple catches are written if or when a try block is expected to throw different types of errors.
Imagine a program that requests some numbers from the user and performs some operation on the
numbers. Such a program can be written as follows:
#include <iostream.h>
int main()
{
double Operand1, Operand2, Result;
char Operator;
cout << "This program allows you to perform an operation on two numbers\n";
cout << "To proceed, enter a number, an operator, and a number:\n";
cin >> Operand1 >> Operator >> Operand2;
switch(Operator)
{
case '+':
Result = Operand1 + Operand2;
break;
case '-':
Result = Operand1 - Operand2;
break;
case '*':
Result = Operand1 * Operand2;
break;
case '/':
Result = Operand1 / Operand2;
break;
default:
cout << "Bad Operation";
}
cout << "\n" << Operand1 << " " << Operator << " "
<< Operand2 << " = " << Result;
cout << "\n\n";
return 0;
}
2.8. Manipulating strings
The C++ strings library provides the definitions of the basic_string class, which is a class template
specifically designed to manipulate strings of characters of any character type.
AVAILABLE OPERATIONS
Creating string objects.
Reading string objects from keyboard.
Displaying string objects to the screen.
Finding a substring from a string.
Modifying string objects.
Adding string objects.
Accessing characters in a string.
Obtaining the size of string.
COMMONLYUSEDSTRINGCONSTRUCTORS
MANIPULATINGSTRINGOBJECTS
1 string s1(“12345”);
2 string s2(“abcde”);
3 s1.insert(4, s2);// s1 = 1234abcde5
4 s1.erase(4, 5);// s1 = 12345
5 s2.replace(1, 3, s1);// s2 = a12345e
MANIPULATINGSTRINGOBJECTS
1 insert()
2 erase()
3 replace()
4 append()
RELATIONALOPERATIONS
PART-A (2MARKS)
29) WRITE THE SYNTAX AND USE OF GETLINE () AND WRITE () FUNCTIONS.
1) WHAT ARE THE VIRTUAL FUNCTIONS? EXPLAIN THEIR NEEDS USING A SUITABLE EXAMPLE.WHAT ARE THE
RULES ASSOCIATED WITH VIRTUAL FUNCTIONS?
2) WHAT ARE THE DIFFERENT FORMS OF INHERITANCE SUPPORTED IN C++? DISCUSS ON THE VISIBILITY OF
ABSTRACT CLASSES.
---------------------------------------------