This practical and simple Stopwatch class shows the basic components of C++ classes.

Stopwatch objects may be used in many programs that require accurate timing.


Background

A class is an abstraction that represents a real-world or system entity.
It contains data (class attributes) and functions (class operations).

An object is an instance of the class (expressed in C++ as a variable with the class as its type).

Stopwatch class diagram

The Stopwatch class has a single data item, startTicks, the number of system clock ticks from the start of the program to the moment the stopwatch was started.

It has two operations:
- start(), which sets startTicks to the number of clock ticks since the program started running.
- getElapsedTime(), which returns the number of seconds (and decimal fractions of second) since the stopwatch was started.

Note that unlike a real stopwatch, this class can return any number of timings from the start of counting.
___________

small stopwatch image Class Header

C++ declares classes in header (.h) files.
A class header presents the class interface, including everything a programmer must know to use the class in programs. It does not include the code implementation of the class which is in the .cpp file.

Stopwatch.h contains the Stopwatch class declaration:

The public: section contains the member functions declarations,
void start(void);
double getElapsedTime(void);

It also displays a default constructor,
Stopwatch();

The constructor is always called when an object is created:
- It is called implicitly when a Stopwatch object is created at compile-time as a local variable for example:
Stopwatch watch; // Constructor called automatically

- It is called explicitly when a Stopwatch object is created dynamically at runtime by using "new":

Stopwatch *watchPtr = new Stopwatch();

Note that "new" returns a pointer to the new object.

Calling a member function of an object requires using the . (dot) notation. For example:
watch.start();
When using a pointer to an object, the -> (arrow) notation must be used instead:
watchPtr->start();

The private: section contains class members (usually mostly data, but sometimes also functions) not directly accessible from outside the class. Private data is maintained and accessed by the public member functions.

Stopwatch maintains information about the number of system ticks from the start of the program to the moment the start() member function is called. It is this information that allows accurate time computation:

clock_t startTicks;

Note that clock_t is a type defined in the standard C header "ctime" (in fact a long integer). In order to have access to this, the header must be #include(d) at the start of Stopwatch.h..

___________

small stopwatch image Class Implementation

The implementation of the class is found in file Stopwatch.cpp. There is no need to look inside this .cpp file in order to use the class; the information in the header is enough (This is called "information hiding, and is great to avoid information overload).

We will now look briefly into Stopwatch.cpp, however, to see how the stopwatch works:

System time is computed accurately by using the system clock() function. It returns the number of clock ticks since the start of the program.
The number of clock ticks is the most accurate time measurement available on any system. A number of clock ticks must be divided by the value of the macro CLOCKS_PER_SEC to obtain the equivalent number of seconds and decimal fractions of seconds. CLOCKS_PER_SEC is defined in the <ctime> header. This is used by the Stopwatch member function getElapsedTime():

/*
 * Report elapsed time in seconds and decimal parts of seconds
 * since start.
 *
 * @return number of seconds since start, or 0 if watch not started.
 */
double Stopwatch::getElapsedTime()
{
	if(!startTicks) // Then current object was not started
 	 	return 0;
 
	// clock(), and CLOCKS_PER_SEC are defined in header <ctime>
	return static_cast<double>(clock() - startTicks) / CLOCKS_PER_SEC;
}

This code checks that the current object startTicks data has been initialised by the start() member function. If that was not the case, the elapsed time returned would be invalid.

If start() has not been called before getElapsedTime(), then startTicks will have value 0 as it is initialised by the constructor. In this case a value of 0 is returned.

In order to compute the elapsed time, a floating point number division must be called. This is ensured by converting the number of system ticks to double prior to division:

static_cast<double>(clock() - startTicks)


- The accuracy of the stopwatch is operating system dependent. On my machine under Windows XP, for example, the number of system ticks is updated only every 20 milliseconds. This is therefore the limit of resolution of the stopwatch for my system. Quite sufficient for most purposes.