Sie sind auf Seite 1von 33

 

August 2010
Master of Computer Application (MCA) – Semester 2
MC0066 – OOPS using C++ – 4 Credits
(Book ID: B0681 & B0715) Assignment Set – 1

1. Describe the steps in compiling and executing a C++ program with programmatic
illustration.
Ans: There are three steps in executing a c++ program: Compiling, Linking and Running the
program. The c++ programs have to be typed in a compiler. All the programs discussed in the
book will be compiled on turbo c++ compiler. The turbo c++ compiler comes with an editor to
type and edit c++ program. After typing the program the file is saved with an extension .cpp.
This is known as source code. The source code has to be converted to an object code which
is understandable by the machine. This process is known as compiling the program. You can
compile your program by selecting compile from compile menu or press Alt+f9. After
compiling a file with the same name as source code file but with extension .obj. is created.
Second step is linking the program which creates an executable file .exe (filename same as
source code) after linking the object code and the library files (cs.lib) required for the program.
In a simple program, linking process may involve one object file and one library file. However
in a project, there may be several smaller programs. The object codes of these programs and
the library files are linked to create a single executable file. Third and the last step is running
the executable file where the statements in the program will be executed one by one.
The below example shows the entire process. When you execute the program, the compiler
displays the output of the program and comes back to the program editor. To view the output
and wait for user to press any key to return to the editor, type getch() as the last statement in
the program. Getch() is an inbuilt predefined library function which inputs a character from the
user through standard input. However you should include another header file named conio.h
to use this function. Conio.h contains the necessary declarations for using this function. The
include statement will be similar to iostream.h.
Example.cpp Iostream.h
(Source code) (Header file)

Cs.lib
(Library file)

Example.obj
(Object code)

Other object
Example.exe codes (if any)
(Executable file)

Compiling and Linking

 
 

During compilation, if there are any errors that will be listing by the compiler. The errors may
be any one of the following

„ Syntax error: This error occurs due to mistake in writing the syntax of a c++ statement or
wrong use of reserved words, improper variable names, using variables without declaration
etc. Examples are : missing semi colon or paranthesis, type integer for int datatype etc.
Appropriate error message and the statement number will be displayed. You can see the
statement and make correction to the program file, save and recompile it.

„ Logical error: This error occurs due to the flaw in the logic. This will not be identified by the
compiler. However it can be traced using the debug tool in the editor. First identify the
variable which you suspect creating the error and add them to watch list by selecting Debug
->Watches->Add watch. Write the variable name in the watch expression. After adding all
the variables required to the watch list, go to the statement from where you want to
observe. If you are not sure, you can go to the first statement of the program. Then select
Debug ->Toggle Breakpoint (or press ctrl + f8). A red line will appear on the statement.
Then Run the program by selecting Ctrl + f9 or Run option from run menu. The execution
will halt at the statement where you had added the breakpoint. The watch variables and
their values at that point of time will be displayed in the bottom in the watch window. Press
F8 to execute the next statement till you reach the end of the program. In this way you can
watch closely the values in the watch variables after execution of each and every statement
in the program. If you want to exit before execution of the last statement press Ctrl + Break.
To remove the breakpoint in the program go to the statement where you have added
breakpoint select Debug ->Toggle Breakpoint (or press ctrl + f8). Select Debug -> watch -
>remove watches to remove the variables in the watch list. This tool helps in knowing the
values taken by the variable at each and every step. You can compare the expected value
with the actual value to identify the error.

„ Linker error: This error occur when the files during linking are missing or mispelt

„ Runtime error: This error occurs if the programs encounters division by zero, accessing a
null pointer etc during execution of the program

2. Describe the theory with programming examples the selection control statements in
C++.
Ans: There are basically two types of control statements in c++ which allows the programmer to
modify the regular sequential execution of statements.They are selection and iteration
statements. The selection statements allow to choose a set of statements for execution
depending on a condition. If statement and switch statement are two statements which allow
selection in c++. There is also an operator known as conditional operator which enables
selection.

 
 

If statement
Syntax : if (expression or condition)
{ statement 1;
statement 2;
}
else
{ statement 3;
statement 4;
}

The expression or condition is any expression built using relational operators which either
yields true or false condition. If no relational operators are used for comparison, then the
expression will be evaluated and zero is taken as false and non zero value is taken as true. If
the condition is true, statement1 and statement2 is executed otherwise statement 3 and
statement 4 is executed. Else part in the if statement is optional. If there is no else part, then
the next statement after the if statement is exceuted, if the condition is false. If there is only
one statement to be executed in the if part or in the else part, braces can be omitted.

Following example program implements the if statement.

// evenodd.cpp
# include <iostream.h>
# include <conio.h>
void main()
{
int num;
cout<<”Please enter a number”<<endl;
cin>>num;
if ((num%2) == 0)
cout<<num <<” is a even number”;
else
cout<<num <<” is a odd number”;
getch();
}

The above program accepts a number from the user and divides it by 2 and if the remainder
(remainder is obtained by modulus operator) is zero, it displays the number is even, otherwise

 
 

as odd. We make use of the relational operator == to compare whether remainder is equal to
zero or not.

Nested If statement
If statement can be nested in another if statement to check multiple conditions.
If (condition1)
{ if (condition 2)
{ statement1;
Statement2;
}
else if (condition3)
{statement3;
}
}
else statement4;
The flowchart of the above example is shown below

Nested If Statement

Multiple conditions can be checked using logical && operator(AND) and || operator (OR).

If ((condition1) && (condition2))


statement1;
else
statement2;

 
 

In the above example statement1 will be executed if both the condition1 and condition2 are
true and in all other cases statement2 will be executed.

If ((condition1 || (condition2))

statement1;

else

statement2;

In the above example statement1 will be executed if either condition1 or condition2 are true
and even if both are true. Statement2 will be executed if both the conditions are false. The
following program demonstrates the use of && operator and nested if statement.

//Large.cpp

# include <iostream.h>

void main()

{ int a,b,c;

cout<<”Please enter three numbers”;

cin>>a>>b>>c;

if ((a>b) && (b>c))

cout<<a<< “ is the largest number”;

else if ((b>a) && (b>c))

cout<<b<< “ is the largest number”;

else if ((c>a) && (c>b))

cout<<c<< “ is the largest number”;

The above program accepts three numbers from the user and displays which is the largest
number among the three.( assumption is that all the numbers are unique, the program has to
be modified if you would like to allow same number twice)

 
 

3. Given a RxC Matrix, A, i.e. R rows and C columns we define a Saddle-Point as


Saddle_Pt (A(i,j)) = A(i,j) is the minimum of Row i and the maximum of Col j.
e.g.
123
456
789
-- 7 is Saddle_Pt. at position (3,1)
Write a program in C++ to check and print for saddle points in a matrix.
Ans: Below is the programme code for saddle point.

//Programm to find saddle point(s) in a matrix

#include<iostream.h>

#include<conio.h>

void main()

clrscr();

int a[3][3],i,j,k,sp,minr,pos,flag=1;

cout<<"Enter the contents of the array ";

for(i=0;i<3;i++)

for(j=0;j<3;j++)

cin>>a[i][j];

cout<<"

The matrix representation of array is: ";

for(i=0;i<3;i++)

cout<<" ";

for(j=0;j<3;j++)

cout<<a[i][j]<<" ";

 
 

cout<<endl;

for(i=0;i<3;i++)

flag=1;

sp=a[i][0],pos=0;

for(j=1;j<3;j++)

if(a[i][j]<sp)

{ sp=a[i][j];

pos=j;

for(k=0;k<3;k++)

if(a[k][pos]<sp)

flag=0;

break;

if(flag==1)

cout<<"The saddle point of row "<<i+1<<" is "<<sp<<endl;

getch();

 
 

4. Describe and Demonstrate the concept of Pass by Value and Pass By Reference using
appropriate programming examples of your own
Ans: Data can be passed to functions in two ways. One method is passing by value. The fact
function discussed in previous section implements passing by value. In this way of passing
variables, a copy of the variable(main program) is created during function call with the name
specified in the function and initialized with the value in the original variable. All the operations
in the function is then performed on the function variable. The values in the variables declared
in the main program remains unchanged by the function operations.

Another alternative to passing arguments is passing by reference. In passing by reference, no


copy of the variable is created. However, the variables in the main program are referred to by
different name in the function. Since no copy is created, when the values in the function
variables are modified, the values in the variables in the main program are also modified.
Passing by reference provides an easy mechanism for modifying the variables by functions
and also enables to return multiple variables.

To pass arguments by reference, all the variable names in the argument list should be
prefixed with & (ampersand) or address of operator during function declaration and definition.
The following example shows the implementation of passing by reference.

Function call is same for passing by reference.

//passingbyreference.cpp

# include <iostream.h>

int swap(int& m, int& n); // function declaration

void main()

int a,b ;

cout<< “enter two numbers”;

cin>>a>>b;

swap(a,b);

cout<<”The value of a is”<<a<<endl;

cout<<”The value of b is”<<b<<endl;

 
 

void swap(int& m, int& n)

{ int temp;

temp=m;

m=n;

n=temp;

In the above program, the variables a and b are passed by reference which implies that they
will be accessed directly. The variables are however will be referred as m and n in the
function and are swapped. The result is that the function swaps the values in the original
variables a and b.

More than one user defined functions can have same name and perform different operations.
This is a powerful feature of C++ and is known as function overloading. Every overloaded
function should however have a different prototype. The following program implements a
overloaded function printline()

//fnoverload.cpp

# include <iostream.h>

void printline();

void printline(char ch);

void printline(char ch, int n);

void main()

printline();

printline(“*”);

printline(“*”, 20);

void printline();

{ for(int i=0;i<25;i++)

cout<<”-“;

 
 

cout<<endl;

void printline(char ch);

{for (int i=0;i<25;i++)

cout<<ch;

cout<<endl;

void printline(char ch, int n);

{ for (int i=0;i<n;i++)

cout<<ch;

cout<<endl;

In the above program, the function printline has three different prototypes depending on the
arguments passed to it. The relevant function is invoked depending on the type and number
of arguments passed to it.

Functions can also contain default arguments. Default arguments are those whose values
need not be explicitly passed during function call. However the default arguments should be
specified in the end of the argument list to avoid ambiguity arising during function overloading.
The default values are specified in the function declaration along with the data type of the
argument. The variable name may or may not be specified during declaration.

The above program can also be implemented through default arguments as shown below.

//defaultarg.cpp

# include <iostream.h>
void printline(char ch=”*”, int n=25);
void main()
{
printline();
printline(“-”);
printline(“-”, 20);

 
 

}
void printline(char ch=”*”, int n=25);
{ for(int i=0;i<n;i++)
cout<<ch;
cout<<endl;
}

As shown in the above example, the values for the variables ch and n will be taken * and 25
respectively if not specified (as in first and second function calls). However if the values are
specified explicitly, then the default values will not be considered.

Arrays can be used as arguments to functions. It is similar to passing any other variables as
shown in the following example

# include<iostream.h>
void display(int arr[3][4]);
void main()
{ int matrix1[3][4], matrix2[3][4], sum[3][4];
int i,j;
cout<<”Enter the elements of matrix one”;
for(i=0; i<3;i++)
for(j=0:j<4;j++)
cin>>matrix1[i][j];
cout<<”Enter the elements of matrix two”;
for(i=0; i<3;i++)
for(j=0:j<4;j++)
{
cin>>matrix2[i][j];
sum=matrix1[i][j]+ matrix2[i][j];
}
cout<<”sum is”;
display(sum);
}
void display(int arr[3][4] )
{

 
 

for(int i=0;i<3;i++)
{for(int j=0;j<3;j++)
cout<<arr[i][j]<<” “;
cout<<endl;}
}
5. Describe the theory of Derivation and Inheritance.
Ans: Derivation: Inheritance is implemented in C++ through the mechanism of derivation.
Derivation allows you to derive a class, called a derived class, from another class, called a
base class.
Derived class syntax:

In the declaration of a derived class, you list the base classes of the derived class. The
derived class inherits its members from these base classes.

The qualified_class_specifier must be a class that has been previously declared in a class
declaration.

An access specifier is one of public, private, or protected.

The virtual keyword can be used to declare virtual base classes.

 
 

The following example shows the declaration of the derived class D and the base classes V,
B1, and B2. The class B1 is both a base class and a derived class because it is derived from
class V and is a base class for D:

class V { /* … */ };
class B1 : virtual public V { /* … */ };
class B2 { /* … */ };
class D : public B1, private B2 { /* … */ };

Classes that are declared but not defined are not allowed in base lists.

For example:
class X;
// error
class Y: public X { };

The compiler will not allow the declaration of class Y because X has not been defined.

When you derive a class, the derived class inherits class members of the base class. You can
refer to inherited members (base class members) as if they were members of the derived
class. For example:

class Base {
public:
int a,b;
};
class Derived : public Base {
public:
int c;
};
int main() {
Derived d;
d.a = 1; // Base::a
d.b = 2; // Base::b
d.c = 3; // Derived::c
}

 
 

The derived class can also add new class members and redefine existing base class
members. In the above example, the two inherited members, a and b, of the derived class d,
in addition to the derived class member c, are assigned values. If you redefine base class
members in the derived class, you can still refer to the base class members by using the ::
(scope resolution) operator. For example:

#include <iostream>
using namespace std;
class Base {
public:
char* name;
void display() {
cout << name << endl;
}
};
class Derived: public Base {
public:
char* name;
void display() {
cout << name << ", " << Base::name << endl;
}
};
int main() {
Derived d;
d.name = "Derived Class";
d.Base::name = "Base Class";
// call Derived::display()
d.display();
// call Base::display()
d.Base::display();
}
Output:
Derived Class, Base Class
Base Class

 
 

You can manipulate a derived class object as if it were a base class object. You can use a
pointer or a reference to a derived class object in place of a pointer or reference to its base
class. For example, you can pass a pointer or reference to a derived class object D to a
function expecting a pointer or reference to the base class of D. You do not need to use an
explicit cast to achieve this; a standard conversion is performed. You can implicitly convert a
pointer to a derived class to point to an accessible unambiguous base class. You can also
implicitly convert a reference to a derived class to a reference to a base class.

The following example demonstrates a standard conversion from a pointer to a derived class
to a pointer to a base class:

#include <iostream>
using namespace std;
class Base {
public:
char* name;
void display() {
cout << name << endl;
}
};
class Derived: public Base {
public:
char* name;
void display() {
cout << name << ", " << Base::name << endl;
}
};
int main() {
Derived d;
d.name = "Derived Class";
d.Base::name = "Base Class";
Derived* dptr = &d;
// standard conversion from Derived* to Base*
Base* bptr = dptr;
// call Base::display()

 
 

bptr->display();
}
Output:
Base Class

The statement Base* bptr = dptr converts a pointer of type Derived to a pointer of type Base.

The reverse case is not allowed. You cannot implicitly convert a pointer or a reference to a
base class object to a pointer or reference to a derived class. For example, the compiler will
not allow the following code if the classes Base and Class are defined as in the above
example:

int main() {
Base b;
b.name = "Base class";
Derived* dptr = &b;
}

The compiler will not allow the statement Derived* dptr = &b because the statement is trying
to implicitly convert a pointer of type Base to a pointer of type Derived.

If a member of a derived class and a member of a base class have the same name, the base
class member is hidden in the derived class. If a member of a derived class has the same
name as a base class, the base class name is hidden in the derived class.

Inheritance: Inheritance is a mechanism of reusing and extending existing classes without


modifying them, thus producing hierarchical relationships between them.

Inheritance: It is almost like embedding an object into a class. Suppose that you declare an
object x of class A in the class definition of B. As a result, class B will have access to all the
public data members and member functions of class A. However, in class B, you have to
access the data members and member functions of class A through object x. The following
example demonstrates this:

#include <iostream>
using namespace std;
class A {
int data;
public:
void f(int arg) { data = arg; }

 
 

int g() { return data; }


};
class B {
public:
A x;
};
int main() {
B obj;
obj.x.f(20);
cout << obj.x.g() << endl;
// cout << obj.g() << endl;
}

In the main function, object obj accesses function A::f() through its data member B::x with the
statement obj.x.f(20). Object obj accesses A::g() in a similar manner with the statement
obj.x.g(). The compiler would not allow the statement obj.g() because g() is a member
function of class A, not

class B.

The inheritance mechanism lets you use a statement like obj.g() in the above example. In
order for that statement to be legal, g() must be a member function of class B.

Inheritance lets you include the names and definitions of another class’s members as part of
a new class. The class whose members you want to include in your new class is called a
base class. Your new class is derived from the base class. The new class contains a
subobject of the type of the base class. The following example is the same as the previous
example except it uses the inheritance mechanism to give class B access to the members of
class A:

#include <iostream>
using namespace std;
class A {
int data;
public:
void f(int arg) { data = arg; }
int g() { return data; }
};

 
 

class B : public A { };
int main() {
B obj;
obj.f(20);
cout << obj.g() << endl;
}

Class A is a base class of class B. The names and definitions of the members of class A are
included in the definition of class B; class B inherits the members of class A. Class B is
derived from class A. Class B contains a subobject of type A.

You can also add new data members and member functions to the derived class. You can
modify the implementation of existing member functions or data by overriding base class
member functions or data in the newly derived class.

You may derive classes from other derived classes, thereby creating another level of
inheritance. The following example demonstrates this:

struct A { };

struct B : A { };

struct C : B { };

Class B is a derived class of A, but is also a base class of C. The number of levels of
inheritance is only limited by resources.

Multiple inheritance allows you to create a derived class that inherits properties from more
than one base class. Because a derived class inherits members from all its base classes,
ambiguities can result. For example, if two base classes have a member with the same name,
the derived class cannot implicitly differentiate between the two members. Note that, when
you are using multiple inheritance, the access to names of base classes may be ambiguous.
See Multiple inheritance section for more detailed information.

A direct base class is a base class that appears directly as a base specifier in the declaration
of its derived class.

An indirect base class is a base class that does not appear directly in the declaration of the
derived class but is available to the derived class through one of its base classes. For a given
class, all base classes that are not direct base classes are indirect base classes. The
following example demonstrates direct and indirect base classes:

 
 

class A {
public:
int x;
};
class B : public A {
public:
int y;
};
class C : public B { };

Class B is a direct base class of C. Class A is a direct base class of B. Class A is an indirect
base class of C. (Class C has x and y as its data members.)

Polymorphic functions are functions that can be applied to objects of more than one type. In
C++, polymorphic functions are implemented in two ways:

· Overloaded functions are statically bound at compile time.

· C++ provides virtual functions. A virtual function is a function that can be called for a number
of different user-defined types that are related through derivation. Virtual functions are bound
dynamically at run time. They are described in more detail a little further in the chapter.

6. Describe the Friend functions and friend classes with programming examples.
Ans: Friend classes in C++ give us access to non-member functions or other classes. By using the
friend keyword, a class can grant access to non-member functions or to another class. These
friend functions and friend classes are permitted to access private and protected class
members. There are places where friends can lead to more intuitive code, and are often
needed to correctly implement operator overloading.

If encountering friend functions for the first time, you might feel slightly uneasy since they
seem to violate encapsulation. This feeling may stem from the fact that a friend function is not
strictly a member of the class. By thinking of a friend function as part of the class’s public
interface, you can get a better understanding of how friends work. From a design perspective,
friends can be treated in a similar way to public member functions. The concept of a class
interface can be extended from public members to include friend functions and friend classes.
Put another way: Friend functions do not break encapsulation; instead they naturally extend
the encapsulation barrier.

Friend Functions: Friend functions can be declared anywhere within a class declaration, but
it is common practice to list friends at the beginning of the class. The public and protected

 
 

keywords do not apply to friend functions, as the class has no control over the scope of
friends.

If we want to declare an external function as friend of a class, thus allowing this function to
have access to the private and protected members of this class, we do it by declaring a
prototype of this external function within the class, and preceding it with the keyword friend:

// friend functions
#include <iostream>
using namespace std;
class CRectangle
{
int width, height;
public:
void set_values (int, int);
int area () {return (width * height);}
friend CRectangle duplicate (CRectangle);
};

void CRectangle::set_values (int a, int b) {


width = a;
height = b;
}

CRectangle duplicate (CRectangle rectparam)


{
CRectangle rectres;
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}

int main ()

 
 

{
CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
return 0;
}

The duplicate function is a friend of CRectangle. From within that function we have been able
to access the members width and height of different objects of type CRectangle, which are
private members. Notice that neither in the declaration of duplicate() nor in its later use in
main() have we considered duplicate a member of class CRectangle. It isn’t! It simply has
access to its private and protected members without being a member.

The friend functions can serve, for example, to conduct operations between two different
classes. Generally, the use of friend functions is out of an object-oriented programming
methodology, so whenever possible it is better to use members of the same class to perform
operations with them. Such as in the previous example, it would have been shorter to
integrate duplicate() within the class CRectangle.

Friend Classes: As well as choosing a non-member friend function, a class has two other
possibilities for its friends. A class can declare a member function of another class as a friend,
or declare another class as a friend class.

Friend classes are used in cases where one class is tightly coupled to another class. For
example, suppose we have a class CPoint that represents a coordinate, and a class
CPointCollection that holds a list of points. Since the collection class may need to manipulate
point objects, we could declare CPointCollection as a friend of the CPoint class:

// Forward declaration of friend class.


class CPointCollection;
// Point class.
class CPoint {
friend CPointCollection;

private:
double m_x;
double m_y;

 
 

public:
CPoint(const double x, const double y) :

m_x(x),
m_y(y) { }

~CPoint(void) { }
// …
};

Since the collection class is a friend of CPoint, it has access to the internal data of any point
object. This is useful when individual elements of the collection need to be manipulated. For
example, a set method of the CPointCollection class could set all CPoint elements to a
particular value (vector is a STL container which is discussed in detail in Chapter 8):

class CPointCollection
{
private:
vector<CPoint> m_vecPoints;

public:
CPointCollection(const int nSize) :
m_vecPoints(nSize) { }
~CPointCollection(void);

void set(const double x, const double y);


// …
};

The set member can iterate over the collection and reset each point:

void CPointCollection::set(const double x, const double y) {

// Get the number of elements in the collection.


const int nElements = m_vecPoints.size();

 
 

// Set each element.


for(int i=0; i<nElements; i++) {
m_vecPoints[i].m_x = x;
m_vecPoints[i].m_y = y;
}
}

One thing worth noting about friend classes is that friendship is not mutual: although
CPointCollection can access CPoint, the converse is not true. Friendship is also not
something that is passed down a class hierarchy. Derived classes of CPointCollection will not
be able to access CPoint. The principle behind this is that friendship is not implicitly granted;
each class must explicitly choose its friends.

7. Illustrate with suitable examples various file handling methods in C++.


Ans: File input and output in C++ is handled completely by predefined file and stream related
classes. The cin and cout statements which we were using for input from keyboard and output
to display screen are also predefined objects of these predefined stream classes.

The header file iostream.h is a header file containing the declarations of these classes which
we have been using in all our programs. Similarly other header file fstream.h contains
declarations for classes used for disk file I/O.

Let us first understand what is a stream. Streams are name given for flow of data. They are
logical abstraction between user and the external device.Each stream is associated and
represented through a class in C++. All streams behave in the same way even though they
are connected to different devices. This capability allows same functions to be used even
though devices are different. The member functions in stream classes contains definitions
and procedures for handling a particular kind of data. For example ifstream class is defined
for handling input from disk files. So the files in C++ are objects of a particular stream class.

The stream classes are organized in a beautiful hierarchy which is slightly complex. But
overview of how they are organized will provide an excellent example of inheritance and help
understand files and streams in a better way.

The following figure shows a portion of stream class hierarchy in C++ which we will be using
in our programs

 
 

Stream Classes in C++: As shown in the fig. 9.1 all stream classes have been inherited from
the base class ios. It contains many constants and member functions common to all kind of
input and output. The class istream is derived from ios class which contains all the necessary
functions for handling input. Some of the functions such as get(), getline(), read and
overloaded extraction (>>) operators are defined in istream class. While ostream class which
is also derived from ios class is dedicated for output related functions of all kinds and contains
functions such as put() and write and overloaded insertion operator (<<).

The class iostream is inherited from both istream and ostream through multiple inheritance so
that other classes can inherit both the functionalities of input and output from it. Three classes
istream_withassign, ostream_withassign, iostream_withassign are inherited from istream,
ostream, iostream respectively which adds assignment operators to these classes.Cout is an
predefined object of the class ostream_withassign class. Cin is an object of the class
istream_withassign class.

The class ifstream which is inherited from both istream and fstreambase is used for input files.
Similarly, class ofstream which is inherited from both ostream and fstreambase is used for
output files. The class fstream inherited from both iostream and fstreambase is used for files
that will perform both input and output. All the three classes for file input and output ie
fstream, ifstream and ofstream are declared in the header file fstream.h. The file fstream.h

 
 

also includes iostream.h, so the programs using fstream.h need not explicitly include
iostream.h.

Character and String input and output to files: Let us see some programs that writes and
reads characters and strings to text file. To write any data to a file, you should create an
object of ofstream class. The function put() is used with the object to write to the file. It
however writes one character at a time. The syntax of put() function is :

objectname.put(character variable).

The following program shows the use of put() function:

#include<fstream.h>
# include<string.h>
void main()
{
ofstream outfile(“test.txt”);
char str[ ]=“hello world”;
for (int j=0;j<strlen(str);j++)
outfile.put(str[j]);
}

In the above program we have created an ofstream object named outfile. The constructor of
the class is invoked and a text file named test.txt is assigned to the object outfile. A text file is
created in the output directory specified in your compiler and if there is already an text file with
the same name, then it is overwritten. The contents of the string str is written to the file
test.txt. Please note that we have include fstream.h header file.

Since the insertion operator (<<) is overloaded in the class ostream class (ofstream is derived
from ostream), it can be used along with the ofstream object to write text directly to the file.
The following program shows that

#include<fstream.h>
void main()
{
ofstream outfile(“test.txt”);
outfile<<“This is my first filen”;
outfile<<“Byen”;
}

 
 

To read data from any file, you should create an object of ifstream class. The function get()
and getline() is used with the object to read the file. The function get() reads one character at
a time. The syntax of get() function is :

objectname.get(character variable)

where object is an object of the ifstream class and the character read is stored in the variable.

The following program reads the contents of a text file character by character and prints on
the screen.

#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
char ch;
clrscr();
while (infile) // infile becomes 0 when eof condition is reached
{infile.get(ch);
cout << ch;}
getch();}

In the above program, we have checked the end of file condition using the objectname itself
which becomes zero when end of file is reached. Alternatively, eof() member function is used
to check end of file condition. It returns non zero value when end of file is reached and returns
zero while it is reading the file.

The getline() function reads line by line as shown in the following program

#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
char buffer[80];
clrscr();
while (!infile.eof()) //returns nonzero value when eof condition is reached

 
 

{infile.getline(buffer,80);
cout << buffer;}
getch();}

Since the extraction operator (>>) is overloaded in the class istream class (ifstream is derived
from istream), it can be used along with the ifstream object to read text. However it reads one
word at a time. The following program shows that

#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
char buffer[25];
clrscr();
while (infile) //infile becomes 0 when eof condition is reached
{infile>>buffer;
cout << buffer;}
getch();}

While reading files, we have assumed that the files have already been existing on the disk.
However it would be wise to include checks that report in case the file you intend to read is
not found on the disk. The ios class contains many such status checks. The above program
has been rewritten with error check while opening the file.

#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
if (!infile) // check for error while opening the file
cout<<”Cannot open file”;
else
{
char buffer[25];
clrscr();

 
 

while (infile) //infile becomes 0 when eof condition is reached


{infile>>buffer;
cout << buffer;}
}
getch();}
8. Explain the concept of class templates in C++ with some real time programming
examples
Ans: Class Templates: class template definition looks like a regular class definition, except it is
prefixed by the keyword template. For example, here is the definition of a class template for a
Stack.
template <class T>
class Stack {
public:
Stack(int = 10);
~Stack() { delete [] stackPtr ; }
int push(const T&);
int pop(T&);
int isEmpty()const { return top == -1; }
int isFull() const { return top == size – 1; }
private:
int size; // number of elements on Stack.
int top;
T* stackPtr;
};

T is a type parameter and it can be any type. For example, Stack<Token>, where Token is a
user defined class. T does not have to be a class type as implied by the keyword class. For
example, Stack<int> and Stack<Message*> are valid instantiations, even though int and
Message* are not "classes".

Implementing Class Template Member Functions: Implementing template member


functions is somewhat different compared to the regular class member functions. The
declarations and definitions of the class template member functions should all be in the same
header file. The declarations and definitions need to be in the same header file.

 
 

Consider the following:

//B.H //B.CPP //MAIN.CPP

template <class t> #include "B.H" #include "B.H"

class b { template <class t> void main() {

public: b<t>::b() { b<int> bi;

b(); } b <float> bf;

~b(); template <class t> }

}; b<t>::~b() {

When compiling B.cpp, the compiler has both the declarations and the definitions available. At
this point the compiler does not need to generate any definitions for template classes, since
there are no instantiations. When the compiler compiles main.cpp, there are two
instantiations: template class B<int> and B<float>. At this point the compiler has the
declarations but no definitions.

While implementing class template member functions, the definitions are prefixed by the
keyword template. Here is the complete implementation of class template Stack:

//stack.h
#pragma once
template <class T>
class Stack {
public:
Stack(int = 10);
~Stack() { delete [] stackPtr; }
int push(const T&);
int pop(T&); // pop an element off the stack
int isEmpty()const { return top == -1; }
int isFull() const { return top == size – 1; }
private:
int size; // Number of elements on Stack
int top;

 
 

T* stackPtr;
};

//constructor with the default size 10


template <class T>
Stack<T>::Stack(int s) {
size = s > 0 && s < 1000 ? s : 10;
top = -1; // initialize stack
stackPtr = new T[size];
}

// push an element onto the Stack


template <class T>
int Stack<T>::push(const T& item) {
if (!isFull())
{
stackPtr[++top] = item;
return 1; // push successful
}

return 0; // push unsuccessful


}

// pop an element off the Stack


template <class T>
int Stack<T>::pop(T& popValue) {
if (!isEmpty())
{
popValue = stackPtr[top--];
return 1; // pop successful
}
return 0; // pop unsuccessful
}

 
 

Using a class template: Using a class template is easy. Create the required classes by
plugging in the actual type for the type parameters. This process is commonly known as
"Instantiating a class". Here is a sample driver class that uses the Stack class template.

#include <iostream>
#include "stack.h"
using namespace std;
void main() {
typedef Stack<float> FloatStack;
typedef Stack<int> IntStack;
FloatStack fs(5);
float f = 1.1;
cout << "Pushing elements onto fs" << endl;
while (fs.push(f))
{
cout << f << ‘ ‘;
f += 1.1;
}
cout << endl << "Stack Full." << endl
<< endl << "Popping elements from fs" << endl;
while (fs.pop(f))
cout << f << ‘ ‘;
cout << endl << "Stack Empty" << endl;
cout << endl;
IntStack is;
int i = 1.1;
cout << "Pushing elements onto is" << endl;
while (is.push(i))
{
cout << i << ‘ ‘;
i += 1;
}
cout << endl << "Stack Full" << endl
<< endl << "Popping elements from is" << endl;

 
 

while (is.pop(i))
cout << i << ‘ ‘;
cout << endl << "Stack Empty" << endl;
}

Output:
Pushing elements onto fs
1.1 2.2 3.3 4.4 5.5

Stack Full.
Popping elements from fs
5.5 4.4 3.3 2.2 1.1

Stack Empty
Pushing elements onto is
1 2 3 4 5 6 7 8 9 10

Stack Full
Popping elements from is
10 9 8 7 6 5 4 3 2 1
Stack Empty

In the above example we defined a class template Stack. In the driver program we
instantiated a Stack of float (FloatStack) and a Stack of int(IntStack). Once the template
classes are instantiated you can instantiate objects of that type (for example, fs and is.)

A good programming practice is using typedef while instantiating template classes. Then
throughout the program, one can use the typedef name.

There are two advantages:

„ typedef’s are very useful when "templates of templates" come into usage. For
example, when instantiating an STL vector of int’s, you could use:

typedef vector<int, allocator<int> > INTVECTOR;

 
 

„ If the template definition changes, simply change the typedef definition. For example,
currently the definition of template class vector requires a second parameter.

typedef vector<int, allocator<int> > INTVECTOR;

INTVECTOR vi1;

In a future version, the second parameter may not be required, for example,

typedef vector<int> INTVECTOR;

INTVECTOR vi1;

Imagine how many changes would be required if there was no typedef!

Das könnte Ihnen auch gefallen