9.15.1. Time Example (Class Version)

Time: 00:16:28 | Download: Large Small | Streaming

The Time example consists of three files illustrating the organization of a larger, realistic program.

Time.h
contains the class specification. Programs realize several benefits by separating the class description from the function definitions:
Time.cpp
contains the member function definitions. Programs only need one copy of these functions. The linker joins the functions' machine code in this file with the calls made throughout the program.
driver.cpp
represents a client of the Time class. In a larger, more realistic program, the client code will typically span many files - some, but perhaps not all, of those files will use the services of a specific class.
The Time UML class diagram:
Time
-----------------
-hours : int
-minutes : int
-seconds : int
-----------------
+Time()
+Time(h : int, m : int, s : int)
+Time(s : int)
+add(t2 : Time) : Time
+print() : void
+read() : void
The Time UML class diagram. There are three important comparisons that you should make between the UML class diagram and the corresponding C++ class specification (Figure 2):
  1. The operation names in the UML diagram match the function names in the class specification
  2. The number and type of the operation parameters in the diagram match the number and type of parameters in the member functions in the class specification
  3. The return type of the operations in the diagram matches the return type of the functions in the class specification

The textbook introduced the Time program in chapter 4 as a structure example. We updated it in chapter 5 to demonstrate that structures can be passed to functions in three ways (a) by value, (b) by pointer, and (c) by reference. Parts of the Time class have been presented in the preceding sections of this chapter to illustrate various aspects of object-oriented programming. The following figures present the complete, final version of the program.

class Time
{
    private:
	int	hours;
	int	minutes;
	int	seconds;

    public:
		Time() : hours(0), minutes(0), seconds(0) {}
		Time(int h, int m, int s) : hours(h), minutes(m), seconds(s) {}
		Time(int s);

	Time	add(Time t2);

	void	print();
	void	read();
};
Time.h: Following the typical pattern, member variables are private, while member functions are public. The three constructors are (top to bottom) default, general, and conversion. The first two constructors use an initializer list to initialize (i.e., store the first value in) the member variables. The first two constructors also qualify as inline functions because their bodies are included inside the class, albeit empty. Although the add function only has one explicit parameter, it is operating on two instances of Time - one instance is passed in through the implicit "this" pointer. print and read also operate on an instance of Time bound to each function by the "this" pointer.
#include <iostream>
#include <iomanip>
#include "Time.h"
using namespace std;


Time::Time(int s)
{
	hours = s / 3600;
	s %= 3600;		// s = s % 3600;
	minutes = s / 60;
	seconds = s % 60;
}


void Time::print()
{
	cout.fill('0');
	cout << hours << ":" << setw(2) << minutes << ":" <<
		setw(2) << seconds << endl;
	cout.fill(' ');
}


Time Time::add(Time t2)
{
	int	i1 = hours * 3600 + minutes * 60 + seconds;
	int	i2 = t2.hours * 3600 + t2.minutes * 60 + t2.seconds;

	return Time(i1 + i2);
}


void Time::read()
{
	cout << "Please enter the hours: ";
	cin >> hours;

	cout << "Please enter the minutes: ";
	cin >> minutes;

	cout << "Please enter the seconds: ";
	cin >> seconds;
}
Time.cpp: Whenever a statement accesses a member variable (e.g., hours, minutes, or seconds) without a dot operator on the left, that variable belongs to the object calling the function and is temporarily bound to the function by the this pointer.

The add function demonstrates the different syntax needed to access the fields that belong to "this" object and the explicit parameter object, t2:

#include <iostream>
#include "Time.h"
using namespace std;


int main()
{
	Time	t;
	t.read();

	t.print();

	Time	s(1, 30, 4);
	s.print();

	Time	u = t.add(s);
	u.print();

	//t.add(s).print();	// alternate

	return 0;
}
driver.cpp: Programs cannot call member functions alone but must call them through an object. For example, a programmer does not write print(); but rather must write t.print(); where t is an instance of the time class. Programs pass objects appearing on the left-hand side of the dot operator by-pointer to the "hidden" this pointer in the member function.

Please note that the alternate code that chains the dot operator works most of the time, but it does fail with some compilers.