DAY – 2
In
yesterday’s class we have seen an overview about object oriented programming
and the different design steps which have to be followed to efficiently solve a
real world problem using this programming technique. Different object oriented
programming languages exist in today’s world. Some examples are object Pascal,
Eiffel, clos and java.
From
today’s class we are going to learn about a very beautiful programming language
named C++ which was developed by a great person named Bjarne Stroustrup. If you notice, you can see that I have not
included this name in the list of object oriented languages. It is because C++
is not considered to be a pure object oriented language instead it is a hybrid
language. In the sense, along with object oriented concepts, C++ supports
procedural language also to the maximum extend.
Or
in other words, C++ is considered to be the superset of C. It has complete
backward compatibility with C language which helps us to used old C program in
our current day C++ compilers. It also helps beginners to easily migrate from C
to C++.
Even though our
aim is to design / find solution for a real world problem using the object
oriented concepts of C++, since this language perfectly supports structured
programming it is possible to write procedural like programs using C++. So
first let’s see how to make use of procedural approach in C++.
Lets write a
very basic program in C++ and see how things work here and how it differs from
your C language.
//My first program in C++
#include <iostream.h>
bool Check_Equal(int, int);
int main()
{
int Val1, Val2;
cout << "Enter the values to
be compared" << endl;
cin >> Val1 >> Val2;
bool Result;
Result = Check_Equal(Val1, Val2);
if(Result)
cout << "Both values are
same" << endl;
else
cout << "Both values
are not same" << endl;
return 0;
}
bool Check_Equal(int V1, int V2)
{
bool Check_Result = V1 == V2;
return Check_Result;
}
Even though the program seems to
be very simple, there are lot of things to be learnt from this program. Let’s
start from the first line and analyze it.
First
line is the comment. How do u write comments in your C language? Usually using
/* */ right. Since C++ is backward compatible with C, it is perfectly legal to
use that here. But usually for one line comments, in C++ , we prefer // to be
used in place of /* */. So while you code your program, make it a practice that
you are using // for single line comments and /* */ for multi line comments.
Second
line as you know is the pre processor directive. As u know, a part of the
compiler called the preprocessor deals with these directives before it begins
the real compilation process. Here it includes the contents of the standard
header file iostream. It is a header with a input output functionality similar
to you stdio.h. It includes the declaration of the standard input output
library in C++ which is later used in our programs.
If you notice here you can see two
functions present in this program. One is main() and the other one is
Check_Equal(int, int). Syntax wise C functions and C++ functions looks the same
right. But even then there are few restrictions in C++ functions.
C++ is a pretty
strict language. In C++, prototype declaration of functions is a must. But in
C, as you know, if arguments and return type are of int type, you can even
avoid the prototype declaration. Again writing functions with no return type is
not allowed in C++ where as C just allows you to move forward with a simple
warning.
Let’s
talk about the first function main(). As you know, it is the starting point of
every program. Immediately followed is the variable declaration. Again similar
to the C style with the difference that in C++ we have the flexibility of
declaring the variables anywhere in the program before it is used. In this program
you can see a variable Result declared
before its use.
When
you compile this program you can c that cout statements behaves like your
printf in C and cin statements behaves like your scanf in C. How does this
work? A complete description of this statement requires a deeper understanding
of the language. For the time being I will jus explain briefly what is
happening here?
cout
and cin are described as the predefined objects of standard output / input
stream. Let’s start with the word stream. Stream just refers to the flow of
data. Or I can say that stream is an imaginary device through which data flows.
Take an eg, lets say this class room, we r having a two way communication here.
The information is flowing from my side to your side and the air between us is
acting as a media / stream through with the data flows. In this example we can
see that for a proper communication there need to be solid persons on either
side of the stream.
Now consider our
programming environment , the data can either flow towards the output side ie)
towards the monitor or the data can even flow towards the input side ie) from
the keyboard. In either cases , you can c that on one side of the stream, we
have a hardware device. To interact with the hardware device, there need to be
a solid person on the LHS. And in our language, this solid person is an object.
We can diagrammatically represent it as below.
cin is a pre defined object in
our library which interacts with the input stream ie) our keyboard and cout is
a pre defined object in our library which interacts with the output stream ie)
our monitor.
cin
always works with an operator known as get from operator with a symbol >>
(also known as extraction operator) and cout always works with an operator
known an put to operator(also known as insertion operator) with a symbol <<. Have you
seen / used these two operators before? Yes right. They were acting as bitwise
operators or more specifically shift operators in our C language. In C++ also,
it is perfectly capable of working with bits. But in this situation, it acts
completely like a new operator. Ie) a single person existing in many forms. An
alternate term for many is “poly” and alternate term for forms is “morph”. So
this property can be called as “polymorphism”. We will talk about it in depth
in our later sessions.
Here
the left shift operator is made to behave like put to operator and right shift
operator is made to behave like get from operator.
The working of
put to operator in association with cout is shown below. The put to operator
inserts the data on the RHS to cout object on its LHS. Since cout is an object
directly associated with monitor, it automatically takes up the responsibility
of pushing the data to the monitor.
Monitor <--------- cout <---------- << <------------------ data
The working of get from operator
in association with cin is shown below.
Keyboard cin >> data
Since cin is directly associated
with keyboard, the data typed from the keyboard will be automatically
associated with cin. The get from operator extracts the contents of cin object
and puts it in the variable on the right.
Hope
you got a general idea about how it works. We will be talking more about these
objects later in our classes.
The
next line in this program which is unfamiliar to u will be the declaration
‘bool b’. This is a declaration similar to ur int a. Boolean is a new data type
introduced in C++. The general syntax for it is
Bool
variable_name
The speciality of boolean is it
can have only two values. True (internally hash defined to 1)and
false(internally hash defined to zero). It is similar to a character variable
of 1 byte but limited to storing only two values. So if ever a character
variable has to manipulated as a flag(which should take only 1 and 0), it is
always better to go for booleans. It is mostly used in logical operations, it
provides more readability to the program.
The
only thing unfamiliar to you in this program now will be endl.As u might have
guessed it is performing the same functionality of your ‘\n’. endl is termed as
a manipulator. Functionality wise the only difference between these two is in
the case of stream buffer. In the sense, every stream is associated with a
buffer. For eg: if you are trying to display something to your monitor, it
doesn’t go directly to the monitor, instead it first goes to an intermediate
buffer. Only when the buffer is full, it is flushed to the monitor. Same is the
case with input buffer also. Now when endl is inserted to the buffer,
internally it actually inserts a \n to the buffer. But it doesn’t wait for the
buffer to get full. Immediately after inserting \n the buffer will be flushed
where as if you are using \n instead of endl, buffer flushing will occur only
when the buffer is full.
Try to compile
this program. You people will be encountering a warning right. A backward
compatibility warning telling you something about the .h extension used along with
iostream.h. Let’s c why this warning is coming and how to avoid this warning.
This warning
arises due to the second line in your program. Ie) include statement. U were
writing it as iostream.h. Now this creates problem in this new compilers. This
is bcos c++ is no longer using .h extensions. If u use some old compiler like
turbo n compile it, it will work perfectly. Now when I tell you that there is
not .h extensions, ur
normal tendency will be remove the .h and compile the program. Even then ur compiler is going to
throw you an error telling that cin and cout are unresolved.
So
how we can solve this problem!! To solve this you have to know about a new
feature introduced in C++ known as namespaces. Now y do u go for namespaces?
Jus consider the eg we took yesterday. Washing machine program. As we
discussed, this program will have small independent modules handled by
individuals.
Each and every module will be
using their own set of variables n functions in their programs. Now as I shown
in the above picture, the variables / functions names used by one module might
have been used by some other module also. While creating the object file for
each module independently, it wont create any problem. But when you try to link
it, the program may show you re-declaration error for the variables n function
names used more than once.
One
way of solving it is instructing each n every programmer to use only a
particular set of variables. But this method is not that feasible. So designers
designed a new technique in which they started creating small blocks. All the
variable n function names used in the program was put inside this block. N when
this variables are accessed outside, they started associating the variable
names to the block name. these blocks were technically termed as namespaces.
The syntax of the namespace is
namespace namespace_name {
//variables
n functions
}
The namespace name is unique
through out. Now even if persons use variables with same name, since it is
inside a particular namespace it won’t cause any re-declaration error.one very
important thing to remember is even though they are inside a so called
namespace block they will still have all the properties of global variables.
Associating the variable with the
namespace name can be done either using a new operator known as scope
resolution operator (::) or using a directive known as “using”. First lets c
how to do with scope resolution operator. Lets take an eg:
//illustrating the effect of
local n global variables
#include <iostream.h>
int Value = 100;
int main() {
int Value = 200;
cout << Value << endl;
return 0;
}
In this program , cout statement
is going to print only 200 since local variables will be having higher
preference over global variables. So if we want to access the global variable
in main, it is our responsibility to explicit tell our compiler that the
variable you are going to access doesn’t belong to the current scope n it
belongs to the global scope. This is done using scope resolution operator n how
u have to write it is ::Value
So rewriting the above program
//illustrating the use of scope
resolution operator in simple program
#include <iostream.h>
int Value = 100;
int main() {
int Value = 200;
cout << Value << endl;
cout << ::Value << endl;
return 0;
}
now applying the same concept to namespaces.
#include <iostream.h>
namespace first
{
int g = 10;
}
namespace second
{
float g = 30.2;
}
int main()
{
cout << first :: g << endl;
cout << second :: g <<
endl;
}
So here you can notice that more
than one namespace is having variables with the same name. lets take a little
more complex example and work on it.
//illustrating namespace using
scope resolution operator
#include <iostream.h>
namespace College_Student {
struct Student {
char Name[20];
int Batch_No;
float Marks;
};
void Display_Details(struct Student
S) {
cout << S.Name <<
endl;
cout << S.Batch_No
<< endl;
cout << S.Marks <<
endl;
}
}
int main() {
College_Student :: Student Anu;
strcpy(Anu.Name, "AnuShri");
Anu.Batch_No = 221;
Anu.Marks = 80;
College_Student ::
Display_Details(Anu);
return 0;
}
Another method of associating
variable names with namespace name is using a keyword termed as “using”. This
keyword can be sued in two different ways.
- Using directive
- Using declaration
Using directive :
The syntax for
using directive is
using
namespace namespace_name;
lets try to modify the above
program using using directive.
//illustrating namespace using
directive
#include <iostream.h>
namespace College_Student {
struct Student {
char Name[20];
int Batch_No;
float Marks;
};
void Display_Details(struct Student S)
{
cout << S.Name <<
endl;
cout << S.Batch_No
<< endl;
cout << S.Marks <<
endl;
}
}
int main() {
using namespace College_Student;
Student Anu;
strcpy(Anu.Name, "AnuShri");
Anu.Batch_No = 221;
Anu.Marks = 80;
Display_Details(Anu);
return 0;
}
If you notice you can see that
once we use the directive, it is like bringing the presence of the entire
variables in the namespace into main. ie) I can use all the variables in the
namespace in the main after my directive statement.
Using declaration:
If using using
declaration, u have to bring the presence of each and every variable in to the
scope where you are using it before using that particular variable. The syntax
for that is
using
namespace_name :: variable_name;
Lets try to modify the above
program with using declaration.
//illustrating namespace using
declarations
#include <iostream.h>
namespace College_Student {
struct Student {
char Name[20];
int Batch_No;
float Marks;
};
void Display_Details(Student S) {
cout << S.Name <<
endl;
cout << S.Batch_No
<< endl;
cout << S.Marks <<
endl;
}
}
int main() {
using College_Student :: Student;
Student Anu;
strcpy(Anu.Name, "AnuShri");
Anu.Batch_No = 221;
Anu.Marks = 80;
using College_Student :: Display_Details;
//declarations
Display_Details(Anu);
return 0;
}
Now if you compare the two
program we get a feeling like directive is simply the cumulative of
declarations right. but it is not at all true. There is a major difference between
directive and declaration. Consider the below program using declaration.
//illustrating difference of
directive n declaration
#include <iostream.h>
namespace College_Student {
struct Student {
char Name[20];
int Batch_No;
float Marks;
};
Student Anu;
void Display_Details(Student S) {
cout << S.Name <<
endl;
cout << S.Batch_No
<< endl;
cout << S.Marks <<
endl;
}
}
int main() {
using College_Student :: Anu;
strcpy(Anu.Name, "AnuShri");
Anu.Batch_No = 221;
Anu.Marks = 80;
using College_Student ::
Display_Details;
Display_Details(Anu);
struct Student {};
Student Anu;
}
Here once I bring the name Anu
from namespace to main, declaration of another variable with the same name in
main is going to through error telling that the names are conflicting. Where as
jus notice the below program with directive
//illustrating difference between
directive and declaration
#include <iostream.h>
namespace College_Student {
struct Student {
char Name[20];
int Batch_No;
float Marks;
};
Student Anu;
void Display_Details(Student S) {
cout << S.Name <<
endl;
cout << S.Batch_No
<< endl;
cout << S.Marks <<
endl;
}
}
int main() {
using namespace College_Student;
strcpy(Anu.Name, "AnuShri");
Anu.Batch_No = 221;
Anu.Marks = 80;
Display_Details(Anu);
struct Student {};
Student Anu;
return 0;
}
Here declaration of another
variable with the same name doesn’t throw any error. Instead the local variable
will simply override the namespace variable.
So which one is better. Using
declaration is always considered to be better since it shows us explicit error
while names conflict.
Now back to our header files and
.h extensions. Before n all, all the libraries were defined globally. The
problem here was, the function names or variable names used in the library
cannot be used by the programmer. For eg: if you try to use strcpy as the name
for ur
function, it will throw you error. This was a burden for the programmer. He has
to think what are the function names he should use in his programs.
Keeping
this thing in mind, the designers have taken away the concept of global header
files. Instead they created new header files without .h extensions. For eg:
iostream. In this new header file, they declared a namespace named as std. N then the contents of the
previous header file was put inside this namespace. So now when ever you want
to use the contents of the header file outside, you have to associate it with
std either using scope resolution or using the directive using.
Now
modifying our first program using all the three methods
//illustrating using scope
resolution operator
#include <iostream>
bool Check_Equal(int, int);
int main()
{
int Val1, Val2;
std :: cout << "Enter the
values to be compared" << std :: endl;
std :: cin >> Val1 >> Val2;
bool Result;
Result = Check_Equal(Val1, Val2);
if(Result)
std :: cout << "Both
values are same" << std :: endl;
else
std :: cout << "Both
values are not same" << std :: endl;
return 0;
}
bool Check_Equal(int V1, int V2)
{
bool Check_Result = V1 == V2;
}
//illustrating using directive
#include <iostream>
bool Check_Equal(int, int);
int main()
{
using namespace std;
int Val1, Val2;
cout << "Enter the values to
be compared" << endl;
cin >> Val1 >> Val2;
bool Result;
Result = Check_Equal(Val1, Val2);
if(Result)
cout << "Both values
are same" << endl;
else
cout << "Both values
are not same" << endl;
return 0;
}
bool Check_Equal(int V1, int V2)
{
bool Check_Result = V1 == V2;
}
//illustrating using declaration
#include <iostream>
bool Check_Equal(int, int);
int main()
{
using std :: cin;
using std :: cout;
using std :: endl;
int Val1, Val2;
cout << "Enter the values to
be compared" << endl;
cin >> Val1 >> Val2;
bool Result;
Result = Check_Equal(Val1, Val2);
if(Result)
cout << "Both values
are same" << endl;
else
cout << "Both values
are not same" << endl;
return 0;
}
bool Check_Equal(int V1, int V2)
{
bool Check_Result = V1 == V2;
}
This is how you have to use
header files in your program and the most commonly used among this is
directive. The C++ designers have even modified the C header files by including
namespaces. For eg: if you want to use stdio.h, remove the .h and add a c
before stdio. Ie) cstdio. Even in this header file there is a namespace named
as std. or I should say that the namespace std; is extended in multiple header
files.
Now we know how to use our header
files and write procedural like program in C++.
REFERENCE :
C++ Complete Reference : Herbert Schildt
C++ Primer Plus : Stephen Prata
0 comments:
Post a Comment