Professional Documents
Culture Documents
COS1512
Semester 2
School of Computing
Bar code
CONTENTS
1 INTRODUCTION ............................................................................................................................ 3
Question 3.………………………………………………………………………………………………………………6
Question 5…………….……………………………………………………………………………………………….26
2
COS1512/ Solution to workshop exercises
1 INTRODUCTION
The purpose of this tutorial letter is to supply the solution for the workshop exercises offered in the
document Workshop Exercises.
The workshop questions were given in the document Workshop Exercises. If you haven't
attempted to do the workshop problems yet, we recommend that you tackle them before referring
to these solutions.
Question 1
The code in bold should be added to the skeleton code for the class declaration. This should be
saved as TimeType.h.
Program Listing:
#ifndef TIMETYPE_H
#define TIMETYPE_H
#include <iostream>
#include <string>
class TimeType
public:
TimeType();
3
int GetSecs() const;
~TimeType();
private:
};
#endif
Question 2
The following program listing should have been produced, after completing steps 3.5 – 3.12. This
should have been saved as TestTimeType.cpp and added to a project, e.g.
TestTimeType.dev.
Program Listing:
#include <iostream>
#include <string>
#include "TimeType.h"
int main()
TimeType time1;
int h,m,s;
4
COS1512/ Solution to workshop exercises
// Question 3.5
h = time1.GetHours();
m = time1.GetMins();
s = time1.GetSecs();
<< h << " minutes = " << m << " seconds = " << s << endl << endl;
// Question 3.6
time1.Set(13,23,59);
h = time1.GetHours();
m = time1.GetMins();
s = time1.GetSecs();
cout << "time1 set to a new value: Hours = " << h << " minutes = " << m
// Question 3.8
TimeType time2(5,30,19);
h = time2.GetHours();
m = time2.GetMins();
s = time2.GetSecs();
cout << "time2 constructed with overloaded constructor: Hours = " << h
<< " minutes = " << m << " seconds = " << s << endl << endl;
// Question 3.9
int allSecs;
allSecs = time1.TimeToSecs();
h = time1.GetHours();
m = time1.GetMins();
s = time1.GetSecs();
<< " minutes = " << m << " seconds = " << s << endl
5
<< " converted to seconds is " << allSecs << " seconds"
<< endl;
// Question 3.10
TimeType time3;
time3.SecsToTime(allSecs);
h = time3.GetHours();
m = time3.GetMins();
s = time3.GetSecs();
cout << allSecs << " seconds converted to time is: Hours = "
<< h << " minutes = " << m << " seconds = " << s << endl
<< endl;
// Question 3.11
TimeType time4;
h = time4.GetHours();
m = time4.GetMins();
s = time4.GetSecs();
cout << "Time difference between time 1 and time 2: Hours = "
<< h << " minutes = " << m << " seconds = " << s << endl
<< endl;
// Question 3.12
return 0;
Question 3
Create another source file TimeType.cpp with the contents below and add to
TestTimeType.dev.
6
COS1512/ Solution to workshop exercises
(NB: this is the implementation file). You should have produced the following implementation file
once steps 3.1 – 3.12 were completed.
// implementation file
#include <iostream>
#include <string>
#include "TimeType.h"
//Default constructor
TimeType::TimeType()
hrs = 0;
mins = 0;
secs = 0;
hrs = initHrs;
mins = initMins;
secs = initSecs;
return hrs;
return mins;
7
}
return secs;
hrs = h;
mins = m;
secs = s;
TimeType::~TimeType()
int seconds;
return seconds;
int remainder;
hrs = s /( 60 * 60 );
remainder = s % ( 60 * 60 );
sout << tt.hrs <<':' << tt.mins << ':' << tt.secs;
return sout;
TimeType Temp;
Temp.SecsToTime(Time3);
return Temp;
Discussion:
C++ has facilities for dividing a program into parts that are kept in separate files, compiled
separately, and then linked together when the program is run. The header (.h) files are effectively
the interfaces of the different classes, and the .cpp files contain the implementations. For this
exercise, you should have created three files:
TimeType.h
TimeType.cpp
TestTimeType.cpp
Only the files with the cpp extension should be ‘added’ to the project.
All files must be in the same directory or folder as the project file (the .dev file).
Both the class specification (or interface) file (the .h file) and the implementation file (a
.cpp file) should contain a using namespace std; statement.
The .cpp files must contain the preprocessor directive to include the .h files.
9
e.g. #include "TimeType.h"
Question 3.1
For this question, the default constructor which initialises the hours, minutes and seconds to 0 had
to be implemented.
Solution:
TimeType::TimeType()
hrs = 0;
mins = 0;
secs = 0;
Discussion:
A constructor is a member function that is automatically called when an object of the class is
declared. A constructor is used to initialize the values of the data members and to do any sort of
initialization that may be required. The constructor has the same name as the class and does not
return a value. The default constructor takes no arguments. The default constructor is invoked
when an object is declared like this:
TimeType t; (For more on default constructors – refer to pages 570-571 of Savitch 6th edition /
pages 602-604 of Savitch 7th edition / pages 598-600 of Savitch 8th edition)
Question 3.2
Solution:
return hrs;
Discussion:
GetHours()signature means that the state of the object cannot be modified. That is, trying to
modify hrs, mins or secs in any way would produce a compilation error. For example the
statements marked by x are not permissible.
hrs = hrs*10; x
mins++; x
secs = 2; x
return hrs;
The const modifier can be used in other contexts as well. Ensure that you study the following
utilization of this modifier as well:
const Parameter Modifier - reference: Savitch pages 616 – 617 6th edition / pages 660-661 7th
edition / pages 650-653 8th edition
Question 3.3
Solution:
return mins;
11
Question 3.4
Solution:
return secs;
Question 3.5
To test the functions implemented above, the following statements had to be added to the file
TestTimeType.cpp:
TimeType time1;
int h,m,s;
h = time1.GetHours();
m = time1.GetMins();
s = time1.GetSecs();
<< h << " minutes = " << m << " seconds = " << s << endl
<< endl;
After compiling and executing TestTimeType.cpp. The following output was produced:
time1 constructed with default constructor: Hours = 0 minutes = 0 seconds = 0
Question 3.6
Solution:
hrs = h;
mins = m;
12
COS1512/ Solution to workshop exercises
secs = s;
time1.Set(13,23,59);
h = time1.GetHours();
m = time1.GetMins();
s = time1.GetSecs();
<< " minutes = " << m << " seconds = " << s << endl << endl;
After compiling and executing TestTimeType.cpp, the following output was produced:
Discussion:
The Set() member function is a mutator. A mutator is a member function that can modify an
object. Every non-const member function of a class is potentially a mutator. In the simplest case,
a mutator just assigns a new value to one of the data members of the class. In general, a mutator
performs some computation and modifies any number of data members (Reference: Savitch,
pages 553-554 6th edtion / pages 585-586 7th edition / pages 581-582 8th edition).
Question 3.7
Solution:
TimeType::~TimeType()
13
After compiling and running TestTimeType.cpp, the following output is produced:
Goodbye!
Discussion:
This destructor actually does not do anything special! Like constructors, destructors are also
functions and do not have a return type. However a class may have only one destructor and the
destructor has no parameters. The name of a destructor is the tilde character (~) followed by the
name of the class. The destructor automatically executes when the class object goes out of scope.
You will encounter more valid destructors as you advance to the second year programming
modules (Reference: Savitch, page 649 – 651 6th edition / page 693 -695 7th edition / page 683 -
685 8th edition.
Question 3.8
Solution:
hrs = initHrs;
mins = initMins;
secs = initSecs;
To test the overloaded constructor, the following statements were added to TestTimeType.cpp:
TimeType time2(5,30,19);
h = time2.GetHours();
m = time2.GetMins();
s = time2.GetSecs();
After compiling and executing TestTimeType.cpp, the following output was produced:
14
COS1512/ Solution to workshop exercises
Goodbye!
Goodbye!
Discussion:
This redefinition overloads the constructor name TimeType so that it may have three arguments.
The overloaded constructor has the same name as the class and does not return a value. This
constructor allows you to instantiate objects of type TimeType, as shown below:
TimeType t1(0,7,30);
TimeType t2(3,4,5);
Question 3.9
Solution:
int seconds;
return seconds;
int allSecs;
allSecs = time1.TimeToSecs();
h = time1.GetHours();
m = time1.GetMins();
15
s = time1.GetSecs();
<< " minutes = " << m << " seconds = " << s << endl
<< " converted to seconds is " << allSecs << " seconds"
<< endl;
After compiling and executing TestTimeType.cpp, the following output was produced:
Goodbye!
Goodbye!
Question 3.10
Solution:
int remainder;
hrs = s /( 60 * 60 );
remainder = s % ( 60 * 60 );
TimeType time3;
16
COS1512/ Solution to workshop exercises
time3.SecsToTime(allSecs);
h = time3.GetHours();
m = time3.GetMins();
s = time3.GetSecs();
cout << allSecs << " seconds converted to time is: Hours = "
<< h << " minutes = " << m << " seconds = " << s << endl
<< endl;
After compiling and executing TestTimeType.cpp, the following output was produced:
Goodbye!
Goodbye!
Goodbye!
Question 3.11
Solution:
17
int Time2 = tt2.TimeToSecs();
TimeType Temp;
Temp.SecsToTime(Time3);
return Temp;
TimeType time4;
h = time4.GetHours();
m = time4.GetMins();
s = time4.GetSecs();
cout << "Time difference between time 1 and time 2: Hours = "
<< h << " minutes = " << m << " seconds = " << s << endl
<< endl;
After compiling and executing TestTimeType.cpp, the following output was produced:
Goodbye!
Goodbye!
Goodbye!
Goodbye!
18
COS1512/ Solution to workshop exercises
Goodbye!
Discussion:
Operator overloading extends the C++ language. Basically it allows us to make operators work
with user defined types. When we overload operators they should also conform to the built-in
version. In other words the overloaded operator should be able to be used in a similar manner as
the built-in operator.
An important point to remember with return types and signatures of operator overloaded functions
is that they are standard. Therefore the general syntax to overload the operator- as a non-
member friend function is:
return temp;
In fact any arithmetic binary operator may be implemented in this way. In other words to overload
operators +, * or / merely replace – above with +, *, / respectively.
Please consider these explanations with relation to the Money class provided in Savitch, Section
11.2, on page 619 6th edition / page 663 7th edition / page 655 8th edition.
Friend functions of a class are actually non-member functions of the class that have access to the
private members of that class (see pages 600 – 618 of Savitch 6th edition / pages 644 – 662 7th
edition / pages 632 – 655 8th edition). Some experts believe that friend functions should be
generally avoided because they can manipulate the underlying data representation of an object.
But there are valid reasons towards its use in terms of operator overloading. Operators may be
overloaded as member functions, or as non-member non-friend functions or as friend functions.
See appendix 8, page 993 of Savitch 6th edition / page 1047 of Savitch 7th edition / page 1034 of
Savitch 8th edition for a complete discussion as to why defining operators as friend functions is
preferable.
Question 3.12
19
Solution:
sout << tt.hrs <<':' << tt.mins << ':' << tt.secs;
return sout;
After compiling and executing TestTimeType.cpp, the following output was produced:
Goodbye!
time1: 13:23:59
time2: 5:30:19
time4: 7:53:40
Goodbye!
Goodbye!
Goodbye!
20
COS1512/ Solution to workshop exercises
Goodbye!
Discussion:
The first expression cout << Time1 would execute by making the call:
This call would then return a reference to cout as the value of cout << Time1 so the remaining
portion of the expression would be interpreted simply as cout << Time2. This would execute by
making the call:
operator<<(cout, Time2 );
(Reference: Savitch, pages 626 – 635 6th edition / pages 670 – 679 7th edition / pages 664 – 667
8th edition)
For this question operator++, had to be implemented. We provide two possible solutions for
operator++. Either one could have been used in the implementation file TimeType.cpp.
Solution 1:
tt.secs++;
tt.secs = 0;
tt.mins++;
tt.mins = 0;
21
tt.hrs++;
tt.hrs = 0;
return tt;
Solution 2:
int s;
s = tt.TimeToSecs();
++s;
tt.SecsToTime(s);
return tt;
The interface is changed accordingly, by including the prototype (shown in bold font):
#ifndef TIMETYPE_H
#define TIMETYPE_H
#include <iostream>
#include <string>
class TimeType {
public:
TimeType();
22
COS1512/ Solution to workshop exercises
~TimeType();
private:
// be reset to 0
};
#endif
++time1;
h = time1.GetHours();
m = time1.GetMins();
s = time1.GetSecs();
<< " minutes = " << m << " seconds = " << s << endl << endl;
After compiling and executing TestTimeType.cpp, the following output was produced:
19
23
time1 Hours = 13 minutes = 23 seconds = 59
Goodbye!
time1: 13:23:59
time2: 5:30:19
time4: 7:53:40
Goodbye!
Goodbye!
Goodbye!
Goodbye!
Discussion:
As mentioned earlier, an important point to remember with return types and signatures of operator
overloaded functions is that they are standard. Therefore the general syntax to overload the pre-
increment operator++ as a non-member friend function is:
//increment whatever by 1
return whatever;
Most modern programming languages allow you to chain operations, that is, they allow several
operators to be used within the same statement. For example: total = a + b + c;. In view
of the fact that, one purpose of operator overloading is to create class operators that work
naturally like built-in operators, you must also create operators for your own classes to have the
same ability. For instance, for the increment operator ++, C++ will allow the following statements:
int a;
++++a;
24
COS1512/ Solution to workshop exercises
This implies that our operator must also be allowed to be used in the same way:
TimeType a;
++++a; // meaning: ++ ++ a;
As operator++ modifies the object, the object must be passed as a reference. The compiler
processes the statement from right to left. When the compiler processes ++a, it interprets it as a
call to operator++(a). Here a, is modified and returned as a reference. Thereafter a is passed
as a reference parameter in a second call to operator++(a). In order for the chaining process to
occur, a reference has to be returned so that a reference may be passed to the next operation in
the chain as operator++ expects a reference parameter (see diagram below).
++
call
operator++(a)
call
operat
The second part of the question required you to test the class Timetype also with the application
program shown below. To do this, open a new project and add the implementation file
TimeType.cpp to it. Type the application program shown below in the main file. The code for
this application program can be downloaded from the departmental website.
#include <iostream>
#include <string>
#include "TimeType.h"
int main()
TimeType time2;
25
cout << "time 2: " << time2 << endl;
int LoopCount;
++time1;
return 0;
Guidelines:
Create a second project, type in / copy the second main application file as given, save it as e.g.
TestTimeType2.cpp, add Timetype.cpp, compile and run.
Output Produced:
time 1: 5:30:0
time 2: 0:0:0
0:4
Goodbye!
Goodbye!
Question 5
For this question you had to classify each of the member functions in the class TimeType as
accessors or mutators.
26
COS1512/ Solution to workshop exercises
Accessors:
GetHours()
GetMins()
GetSecs()
TimeToSecs()
Mutators:
Set()
SecsToTime()
Unisa 2012
27