<Previous Lesson

Introduction to Programming

Next Lesson>

Lesson#38

Lesson 38

Summary


46) User Defined Manipulator
47) Examples of user defined manipulator
48) Static keyword
49) Static Objects
50) Static data members of a class
Today, we will discuss the concepts like ‘user-defined manipulators’ and ‘static
keywords’. Despite being considered minor subjects, these become very important while
carrying out complex programming. Let’s start with ‘User-defined manipulators’.

 

User Defined Manipulators


We have talked a lot about the manipulators that are provided with the streams in the
C++. These are similar to ‘setw’ function, used to set the width of the output. These are
employed as inline like cout << endl << i; Remember that these functions work for only
the immediately next output. How can we write our own manipulator? To determine it, it
is better to understand what parameter-less manipulators are? These are the manipulators
without any parameter like endl. This is a parameter-less built-in manipulator that inserts
the new line besides flushing the buffer. If we want to write our own manipulator, how
can we do this? In case of operator overloading, it is pre-requisite to know that where the
operator will be used, what will be on its left-hand and right-hand sides. On reviewing the
manipulators, you will find a stream object, normally on the left-hand side. Here, we are
talking about ostream, an output stream. So that object will be cout. The cout will take
this manipulator to carry out some manipulation. These are written in cascading style as
cout << manipulator << “some data” << end
l. With this cascading style, you can get a
hint about the operation of this manipulator and its requirements. The point is, the leftCS201
– Introduction to Programming

Page 482
hand side is going to be ostream object that will call the manipulator. What will be
passed to the manipulator and what will be the return type.
Normally on the right-hand side of the manipulator, we have another stream insertion
operator i.e. <<. Here we are considering a parameter-less manipulator, that is no
argument or number will be passed to it. It may be something like inserting a tab between
two numbers for formatting or a manipulator to end the line or to make a sound of bell
and so on. The left hand side is ostream object. There are no other parameters. The righthand
side is normally a stream insertion operator. We use it as cout << manipulator
which is itself an action. We overload the stream insertion operator in such a way that the
cascading works. So we return an ostream object. More accurately, a reference to
ostream
objects is returned. Manipulator is also going to be used in the same way, so that
it returns a reference to an object of type ostream. Therefore we want to return the cout
object or whatever stream we are using. Secondly it also needs the object that is calling it.
Here we are not talking about our own class. ostream class is built-in and not under our
control. So it can not be modified. We can only extend it by defining external things. So
it is not a member function or member operator, but only a standalone operator. Normally
the declaration of this manipulator is as:
ostream& manipulator_name (ostream& os)
This is also not a friend function. We cannot define friends for the classes that are already
written and not in our control. The argument os here is the same object which is calling
this function. We have to explicitly declare it. After this, we have to define this.
Definition is just as another function. You can always write whatever you want inside the
function. But we have to look at the spirit of the manipulator. When we are talking about
the spirit of the manipulator, it means that the manipulator should only do something
regarding output and return. It is normally very simple. Its return type is ostream object.
In case of tab character, we can write as return os << ‘\t’; It can be bell or something
else. We can write useful manipulators to leave single or double blank lines or formatting
the strings etc. Remember that it has to return a reference of object of type ostream. It
automatically gets that object as parameter passed in to the function.

Examples of user defined manipulator


Here is the sample program using the manipulators.
/* A small program which uses the user defined manipulators.
*/
#include <iostream.h>
#include <stdlib.h>
// Gives System Beep
ostream & bell ( ostream & output ) // Manipulator
{
Page 483
return output << '\a' ;
}
// Gives Tab
ostream & tab ( ostream & output ) // Manipulator
{
return output << '\t' ;
}
// Takes the cursor to next line
ostream & endLine ( ostream & output ) // Manipulator
{
return output << '\n' << flush ;
}
void main ( )
{
cout << "Virtual " << tab << "University" << bell << endLine ; // Use of Mainpulator
system ( "PAUSE" ) ;
}
Lets see another example of matrix using the user defined manipulators for displaying the
matrix on the screen.
Here is the code:
/*
A small program showing the use of user defined manipulators.
The display function of matrix is using these manipulators to
format the display.
*/
#include <iostream.h>
#include <stdlib.h>
#include <iomanip.h>
// definition of class matrix
class Matrix
{
private:
int numRows;
int numCols;
float elements[3][3];
public:
// constructor
Matrix(int rows = 0, int cols = 0)
Page 484
{
numRows = rows ;
numCols = cols;
}
// overloading the extraction and insertion operators
friend ostream & operator << ( ostream & , Matrix & );
friend istream & operator >> ( istream & , Matrix & );
// defining the user defiined manipulators
friend ostream & spaceFirst ( ostream & );
friend ostream & spaceBetween ( ostream & );
friend ostream & line ( ostream & );
friend ostream & newLine ( ostream & );
friend ostream & star ( ostream & );
friend ostream & sound ( ostream & );
};
//defining the operator >>
istream & operator >> ( istream & input , Matrix & m )
{
for ( int i = 0 ; i < m.numRows ; i ++ )
{
for ( int j = 0 ; j < m.numCols ; j ++ )
{
input >> m.elements [ i ] [ j ] ;
}
}
return input;
}
//defining the operator <<
ostream & operator << ( ostream & output , Matrix & m )
{
for ( int i = 0 ; i < 60 ; i ++ )
{
if ( i == 30 )
{
output << "Displaying The Matrix" ;
}
else
{
output << star ;
}
}
output << newLine;
for ( int r = 0 ; r < m.numRows ; r++ )
{
Page 485
output << spaceFirst << line;
for ( int c = 0 ; c < m.numCols ; c++ )
{
output << spaceBetween << m.elements [ r ] [ c ] << sound << spaceBetween ;
}
output << spaceBetween << line;
output << newLine;
}
output << newLine;
return output;
}
//defining the user defined manipulator, inserting the space
ostream & spaceFirst ( ostream & output )
{
output << setw(33);
return output;
}
//defining the user defined manipulator, inserting the space
ostream & spaceBetween ( ostream & output )
{
output << setw ( 4 );
return output;
}
//defining the user defined manipulator, inserting the | sign
ostream & line ( ostream & output )
{
output << "|" ;
return output ;
}
//defining the user defined manipulator, inserting the new line
ostream & newLine ( ostream & output )
{
output << endl;
return output;
}
//defining the user defined manipulator, inserting the *
ostream & star ( ostream & output )
{
output << "*" ;
return output ;
}
//defining the user defined manipulator, making sound
ostream & sound ( ostream & output )
{
output << "\a" ;
Page 486
return output ;
}
// the main function
int main ( )
{
// declaring a matrix of 3*3, taking its input and displaying on the screen
Matrix matrix( 3, 3);
cin >> matrix;
cout << matrix;
system("PAUSE");
return 0;
}
The output of the program:
3
5
1
8
7
6
2
5
2
******************************Displaying The Matrix*****************************
| 3 5 1 |
| 8 7 6 |
| 2 5 2 |
Press any key to continue . . .

Static keyword


We have been using static keyword in our examples. What is the meaning of static? The
word refers to something that is stationary, stopped and not moveable. What are the types
of these variables, declared as static? How can we make use of them? Static as the word
implies are variables which exist for a certain amount of time, much longer than that by
ordinary automatic variables. Let’s consider the example about the lifetime of data
variables. One of the variable types is global variable. Global variables are those that are
defined outside of main. They are written as standalone statements before main function
as int i; the variable i is a global variable. It is not only accessible in main but also in all
the functions. They can assign some value to i or obtain the value of i. Global variables
come into existence whenever we execute the program and the memory is allocated for i.
It exists all the time when the program is running. At the end of the program execution,
the memory will be de-allocated and returned to the operating system. So it has a very
Page 487
long lifetime. We need a value which exists for the complete execution of the program
and is available in all the functions. We use global variables. It is not a good idea to do
that unless it is absolutely necessary. The major plus point of these variables is that these
are accessible from everywhere in the program. The inconvenience is that theses
variables are visible in those functions too which does not need them.
Suppose, we have a global variable i declared as int i; and in some function we are
writing a for loop as for(i = 0; i < n; i++); Now which i is being used here. This is the
variable i, declared as global. This global i may have some valuable value, like the
number of cars or the number of students etc. Here, in the function when we run the loop,
the value of i will be changed. The global variables have this bad habit of being around,
even when we don’t need them. What will happen if we declare another i variable inside
the function? A local variable will be created inside the function at run time and the
global i is not going to be accessible. But this can be very subtle and hard to track
programming errors. These are not syntax errors but logical ones. So beware of using too
many global variables. Now have a look on the other side of the picture. While writing
functions, we pass values to them. So instead of passing the value of i again and again,
we declare it as global. Now it is available in the function, leaving no need of passing it.
Let’s now come to the next variety of variables. The variables, defined in the main
function are local to the function main. It means that they are accessible in all parts of the
main function. Their values can be assigned, used in computations and later displayed.
When we enter some function other than main, these variables are not accessible there.
They are hidden. The global and the local variables, declared in a function are visible.
The arguments passed to a function, are also visible. We pass the parameters through
stack. Parameters are written on the stack. Later, the function is called which reads from
the stack and makes a temporary copy for its use. The variables, declared and used inside
the function are called automatic variables. They automatically come into being when the
function is called. When the function finishes, these variables are destroyed. So automatic
variables are created constantly and destroyed all the time. Here, we are talking about
variables ordinary as well as user defined objects. Their behavior is same. They are
automatic when the function is called, memory is allocated normally on the stack at the
same time and used. When the function exits, these variables are destroyed. What
happens if we want that when the function exits, some value, computed inside the
function, is remembered by the function and not destroyed. This should not be visible by
the other parts of the program.
Let’s consider the example of a refrigerator. When we open the door of a refrigerator, the
light turns on and we can see the things inside it. However, on closing the door, the light
turns off. Do we know that light is off because whenever we open the door the light is on.
When we close the door what is inside. We do not know. May be things magically
disappear. When we open the door, magically, the things are at their position. You can
think of this like a function. When we enter in the function, these automatic variables are
available there and visible. When we came out of the function, it is like closing the door
of the refrigerator and the light is turned off. We cannot see anything. Function goes one
step ahead of this and it actually destroys all the variables. Whereas, in the refrigerator,
Page 488
we know that things are there. Somehow we want the function to behave like that.
Outside the refrigerator, these things are not available. We can not access them. Let’s say
there is a bottle of water inside the refrigerator. You open the door and place it some
other place. Next time, when you will open the door, the bottle is seen at the same
position where you have moved it. It would not have moved to some other position. If
you think of automatic variables, suppose we say inside the body of the function int i =
0;
Every time the function is called and you go into the function where i is created. It has
always the value 0 to start with and later on we can change this value.
What we want is that whenever we go back into the function, once we call the function
like we open the door of the refrigerator and move the bottle to some other place and
close the door. So we made one function call. Next time, when we call the function, the
bottle is found in its new place. In other words, if we have defined an integer variable, its
value will be set at 10 in the function when we return from the function. Next time when
we call the function, the value of that integer variable should be 10 instead of 0. We want
somehow to maintain the state of a variable. We want to maintain its previous history.
If we declare a global variable, the state would have been maintained. The global variable
exists all the time. Whatever value is set to it, it is there and accessible from any function.
The drawback is that variable exists even when we don’t want it. Static keyword allows
us a mechanism from getting away of the downside of the global variables and yet
maintaining a state inside a function. When we visit, it is found out what are its values
before that we go ahead with this value. For this, whenever we declare a variable inside
the function, static keyword is employed before the variable declaration. So we write as:
static int i;
That declares i to be a static integer inside the function. Think about it. Should we declare
static variables inside the main function? What will happen? ‘main’ itself is a function so
it is not illegal. There is no objective of doing this in main because main is a function
from where our programs start and this function executes only for once. So its state is like
an ordinary variable, declared inside main. It is only relevant for the called functions. We
write inside the function as static int i; while initializing it once. It will be created only
once irrespective of the number of function calls. Now once it is created, we increment or
decrement its value. The function should remember this value. The programmer may go
out of the function and come back into it. We should get the value that should be same as
that at the time of leaving the function. It is necessary for the static variables that when
these are created, they should be initialized. This initialization will be only for once for
the complete life cycle of the program. They will be initialized only once.
Here, we have to take care of the subtle difference. In case of ordinary variable
declaration, we should initialize them before using. If you have to initialize an int with
zero, it can be written as int i; and on the next line i = 0; But in case of static variables,
we have to use a different type of initialization. We have to use it as static int i = 0; It
means that creation of i and the allocation of memory for it takes place simultaneously. It
is initialized and the value 0 is written. This is initialization process. If somewhere in the
Page 489
function, we have statement i = 10; it will not be treated as initialization. Rather, it is an
assignment statement. Here we want that as soon as the variable is created, it should be
initialized. This initialization will be only for once for the lifetime of the program and it
takes place when first time we enter in to the function. However we can manipulate this
variable as many times as we want. We can increment or decrement it. However, it will
remember its last value. How does this magic work? So far, we have been talking about
the stack and free store. There is another part of memory, reserved for the variables like
static variables. On the stack, automatic variables are being created and destroyed all the
time. The heap or free store has the unused memory and whenever we need memory, we
can take it from there and after use return it. This is the third part which is static memory
area where static variables are created and then they exist for the rest of the program.
These variables are destroyed on the completion of the program. So they are different
from automatic variables which are normally created on stack. They are different from
dynamic variables that are obtained from free store.
To prove this whole point let’s write a simple program to fully understand the concept
and to see how this works. Write a small function while stating that static int i = 0; Here,
we are declaring i as a static integer and initializing it with zero. Then write i++; print
the value of i using cout. Now this function just increments the value of i. This i is a static
integer variable inside the function. Now write a main function. Write a loop inside the
main and call this function in the loop. Let’s say the loop executes for ten times. You will
notice that whenever you go inside the function, the value of i is printed. The value of i
should be printed as 1.2.3…10. If you remove the word static from the declaration of i,
you will notice that every time 1 is printed. Why 1? As i is now automatic variable, it is
initialized with zero and we increment it and its value becomes 1. cout will print its value
as 1. When we return from the function i is destroyed. Next time when function is called,
i
will be created again, initialized by zero, incremented by 1 and cout will print 1. By
adding the static keyword, creation and initialization will happen once in the life time of
our program. So i is created once and is initialized once with the value of zero. Therefore
i++
will be incrementing the existing value. At first, it will become 1. In this case,
function will return from the loop in the main program, call this function again. Now its
value is 1, incremented by 1 and now the value of i becomes 2 and printed by cout. Go
back to main, call it again and so on, you will see it is incrementing the last value. You
can prove that static works.
Here is the code of the program:
/* This is a simple program. This shows the use of static variables inside a function.
*/
#include <iostream.h>
void staticVarFun();
void nonstaticVarFun();
void main(void)
Page 490
{
cout << "\nCalling the function which is using static variable \n";
for(int i = 0; i < 10; i++)
staticVarFun();
cout << " \nCalling the function which is using automatic variable \n";
for(int i = 0; i < 10; i++)
nonstaticVarFun();
}
// function definiition using static variables
void staticVarFun()
{
static int i = 0;
i++;
cout << "The value of i is:" << i << endl;
}
// function definiition using automatic variables
void nonstaticVarFun()
{
int i = 0;
i++;
cout << "The value of i is:" << i << endl;
}
The output of the program:
Calling the function which is using static variables
The value of i is:1
The value of i is:2
The value of i is:3
The value of i is:4
The value of i is:5
The value of i is:6
The value of i is:7
The value of i is:8
The value of i is:9
The value of i is:10
Calling the function which is using automatic variables
The value of i is:1
The value of i is:1
The value of i is:1
The value of i is:1
The value of i is:1
Page 491
The value of i is:1
The value of i is:1
The value of i is:1
The value of i is:1
The value of i is:1

Static Objects


Let us look at some more uses of this keyword. As mentioned earlier that the user defined
data types are the classes and objects that we created. These are now variables as for as
we are concerned. If these are variables, then we can declare them as static. Now we have
to be careful when we think about it. When we declared static int, we said that it should
be initialized there. We initialized it with zero. What is the initialization of objects? We
have defined a class and instantiated an object of that class. So we can say something like
vehicle A or truck B where vehicle and truck are the classes which we have defined. ‘A’
and ‘B’ are their objects, being created in some function or main. When are these objects
initialized? You know that the initialization is done in constructors. So normally C++
provides a default constructor. Here we have to write our own constructors as
initialization can happen only once, if declared static. Again we are talking about these
static objects inside a function instead of the main. These objects should maintain their
values while getting out of the function.
Whenever we create a static object, it must be initialized. Most of the time, we want that
when the object of our class is created, its data members should be initialized by some
value. For this purpose, we have to provide a constructor so that whenever an object is
created, its data members are initialized. Only then it will work. Otherwise we will have
problems. We may want to do as truck A, but our constructor takes some arguments.
Now how this object will be created. How many wheels this truck will have? How many
seats will be there? We have a solution to overcome this problem. Define a constructor
which takes arguments and provides the default value to it simultaneously. If you provide
a constructor with default values, then the object which is created will automatically get
these values. If you write truck A(4, 6), there may be some constructor which will
initialize it with 4 wheels and 6 seats. But the point to remember is if you ever go to use a
static object, it is necessary to provide a constructor with default arguments so that the
object which you have created is initialized properly. Other than that the whole behavior
of a static object is exactly the same as we have a static variable of an ordinary data type
or native data type. Static variable means maintaining the state of a variable. It exists and
lives around even when we are outside the function. It is an alternative to using a global
which exists even when we don’t want it. Now we try to learn about the destructors of
static objects. If you create an object inside a function as truck A, when the function
finishes, the object A will be destroyed. Destructor for this static object will be called.
To prove this write a class, inside the constructor. Also write a cout statement which
should print ‘inside the constructor of ’and the name of the object which will be passed as
an argument. In the destructor write a cout statement as cout <<” Inside the destructor of
Page 492
” << name
, where name will tell us that which object is this. Now experiment with it.
Declare a global variable of this class before main as truck A(‘A’). When the constructor
for this object is called the line ‘Inside the constructor of A’ will be displayed. Now
within the main function, declare another object as ordinary variable i.e. truck B(‘B’). Its
constructor will also be called. You will see it. Write a small function and create another
object within that function as truck C(‘C’). Define another function and declare a static
object in it as truck D(‘D’). Call these two functions from main. Now compile and
execute this program, as we have written cout statements inside the constructor and
destructor. Now you will be able to determine which object is being created and which
one being destroyed. Here you will also notice that first of all global object A will be
created. There is going to be a line ‘Inside the constructor of object A’. After that, object
B
will be created, followed by the display of constructor cout line. From main, we are
calling function F which is creating object C. So object C will be created then. What
next? The function F will finish and the control go back to main. If the function F
finishes, its local data will be destroyed. So the object C will be destroyed. Here, you see
it on the screen ‘Inside the destructor C’. After this the function G will be called and we
will have ‘Inside the constructor for D’. This object D is a static object. Now when the
function G finishes, you will not see the destructor line for object D. After this, the main
function finishes and the destructors will be called for objects A (which is global), object
B
(which is inside the main) and object D (which is created as static inside the function
G). In which order these will be called?. If you look at this very simple program, you will
find that the last object to be created was the static object inside the function G. Should
that deleted first i.e. the destructor of object D should be called? Well actually not true,
the local variables of main function will be first destroyed. Static objects remain for
longer period of time. Later, the static object D will be destroyed and the thing finally
destroyed is the global object, which was created first of all. You will find that the
destructor for object A is called. With this exercise, you will know the sequence in which
things are created and destroyed. Another thing that you will notice is that when the
function G finishes the static object is not destroyed.
The code of the program;
// An example of static objects, notice the sequence of their creation and destruction
#include <iostream>
// defining a sample class
class truck {
private:
char name; // Identifier
public:
// constructor displaying the output with the object name
truck(char cc):name(cc) {
cout << "inside the constructor of " << name << endl;
}
// distructor displaying the output with the object name
~truck() {
Page 493
cout << "Inside the destructor of " << name << endl;
}
};
// defining a global object
truck A('A');
// a simple function creating an object
void f() {
truck C('C');
}
// a simple function creating a static object
void g() {
static truck D('D');
}
// main function
int main() {
// an ordinary object
truck B('B');
// calling the functions
f();
g();
}
The output of the program:
inside the constructor of A
inside the constructor of B
inside the constructor of C
Inside the destructor of C
inside the constructor of D
Inside the destructor of B
Inside the destructor of D
Inside the destructor of A
Lets recap these concepts. When you declare a static variable (native data type or object)
inside a function, it is created and initialized only once during the lifetime of the program
and therefore it will be destroyed or taken out of memory only once during the lifetime of
the program. So it is a good way of maintaining state. It is an alternative to using a global
data type which has some side effects. In the main, we can write static variables but it is a
meaningless exercise because these are exactly like ordinary variables inside main.

Static data member of a class


Lets talk about the keyword static inside the class. Static variables are used to maintain
state. We are talking about the state in which we left the function. While extending the
concept, we will go inside an object. Here, we should find certain things left exactly the
Page 494
way they were initially. So now we are talking of static data members inside a class.
What does it mean?
Literally speaking, the word ‘Static’ means the stationary condition of things. Stationary
for object or class? Here it will be stationary for the class. That means that static data will
be created once and initialized once for that class. Therefore it is not related to the objects
of that class. There is only one copy of the static data member inside a class. The copy is
not repeated for the objects. Whenever we create an object of a class, the complete data
structure is copied for that object and there is one copy of functions which the objects
may use. Static members are single for the whole class in the static memory area. It will
not be repeated whenever we create an object of the class.
Now the question arises when it will be created? When it will be initialized? And when it
will be destroyed? Now these are on class level and not on object level. To understand
this, we have to talk about the lifetime of the static data member. The lifetime of the
static data member of a class is the lifetime of the program. In other words, when you
include a class in the program as a class definition, the memory is allocated for its static
data members. We have some techniques to initialize it. We initialize it only once.
Initialization is done at file scope which means almost at the global scope. We initialize it
outside of the main. The memory is allocated for these static members. No other copy can
be created for them. Therefore we can create and initialize them outside of main. There is
no object so far. How can we initialize its static data members?
Suppose we have a class truck as:
class truck{
public:
int wheels;
int seats;
}
Now we refer the data members with the object as:
truck A;
A.wheels = 6;
A.seats = 4;
That’s a way to refer to a data member. Here we are saying that we have some static data
member of class and the object A has not been created yet. But we have the memory for
the static members. Now we want to initialize that memory. How can we do that? We do
this by using the scope resolution operator (::) and on its left hand side, we have class
name and not the object name. On the right side, we write the name of the static data
member. Suppose we have some static integer data member i in the class truck, so we can
write it as:
truck::i = 10;
Page 495
This initialization is taking place at file scope outside of the main .As it is happening only
once in the program, it will not be executed again. It is being initialized once for the
class. You can create as many object as you want. Objects can read and change that
value.
Static data members of a class can be public or private. The objects of the class have
access to them. They can manipulate it. But it is created and initialized only once. There
is a single copy of these static data members regardless of how many objects of the class
you create.
Let’s take a look at the problems having static data members of a class. Suppose we have
a class as ‘savingsAccount’. We deposit money in that account. Some profit is also
earmarked for it. Over a period of time, bank declares the rate of the profit. Profit rate is
same for all PLS accounts. We have defined a class savingsAccount which have the
information like person name, account number, current balance etc. We also have to keep
the profit rate so that we can apply that on the account. Do we have different profit rate of
every account? No, the bank has declared say 3% profit rate. That will be applied to all
the PLS accounts. So we want that the profit rate should be defined at one place. It should
be the part of the class but not defined for each object. So it is a good place to use a static
variable as a data member of the class. We can initialize it at file scope as:
savingsAccount::profit_rate = 3.0;
We will write this before main function. As soon as, we compile the program and try to
run it, the space is created in the static storage area. The above statement will initialize
that static memory with 3.0. No savings account has been created yet. We will be creating
saving accounts (object of class savingsAccount) in the main or some other function as
account1, account2, etc. This profit rate will be available to every account. We can access
it as:
account1.profit_rate;
and can use it in computations. This is legal but a bad usage. Why it is a bad usage?
Suppose we write as;
account1.profit_rate = 4.0;
What will happen? Does the profit rate for only account1 has been changed? No. There is
only one copy of profit_rate for all the objects of this class. That means if an object
manipulates the static data member, which it can through the member functions or
directly depending on it is private or public. It is actually modifying the value of that
static data member for all objects of this class. So don’t assume that it will change
profit_rate for one object. It is a legal but a bad usage. Always use it with the class name
and not with the object. So you should access it as savingsAccount::profit_rate. It means
you are resolving it at class scope. Be careful while applying it.
Page 496
Let’s consider another example. We have a class as student and a data member for how
many students in the class. Now every time, a student enrolls in the course, we want that
number of students should be incremented. Whenever a student withdraws, fails or passes
out from the course, the number of students should be decremented. We want this to be
inside the student class. How does it work? We define a static data member as static int
how_many;
and initialize it to zero as:
student::how_many = 0;
In the constructor of the class we write as:
how_many++;
This way, whenever a student object is created, how_many will be incremented.
Whenever a student leaves the course, its destructor should be called. We will write in the
destructor as:
how_many--;
So it’s a good way of keeping track of how many objects of a particular type exist at this
time inside the program. To display that we can write a member function that will display
‘how_many’. The merit of this technique is that we have done all this work inside the
class. We did not use two classes or global variable or go through the source code to
count the number of students. Using these, you can make your program more and more
dynamic. The usage of static is very import. So you should understand it clearly. Static is
maintaining the state. The state may be how many students are in the class.
Today we have covered the parameter-less manipulators which will return the ostream
object and ostream object is passed as an argument to them. Then we discussed about the
static data, both at the ordinary level and then the static data members inside the class.
These are very useful. As you write bigger and more complex programs, you will find
that these concepts are very useful. Again from a generic prospective, you will be
working hopefully in your professional career with many different languages. You have
to understand that every language might represent the static concept in a different way.
But just knowing that concept empowers you and help you to understand more complex
programming languages as well.

<Previous Lesson

Introduction to Programming

Next Lesson>

Home

Lesson Plan

Topics

Go to Top

Copyright © 2008-2013 zainbooks All Rights Reserved
Next Lesson
Previous Lesson
Lesson Plan
Topics
Home
Go to Top