You are on page 1of 120

COS1512/101/3/2011

IMPORTANT INFORMATION
Read this tutorial letter first.
It contains the compulsory assignment.

SCHOOL OF COMPUTING

COS1512

Introduction to Programming 2

IMPORTANT INFORMATION: READ NOW


This is a semester module.

Plan to spend at least 8 hours per week on this module.

To be considered for examination admission in COS1512, a student must meet the following
requirement:
Submit assignment 1 BEFORE 14 March 2011 (first semester registration)
OR
Submit assignment 1 BEFORE 22 August 2011 (second semester registration)

Tutorial Letter 101:


First Tutorial Letter
2

This tutorial letter (COS1512/101/3/2011) as well as tutorial letter COSALLF/301/4/2011 contains important
information that you are going to need during the year. Please read them carefully.

Another publication which can be of real help is the brochure My studies@ Unisa. It contains information
about microcomputer laboratories, the library, myUnisa, assistance with study skills, et cetera.

Contents
1 Introduction ................................................................................................................................................................... 4

2 Purpose and outcomes of this module .......................................................................................................................... 4

3 Tutorial Matter .............................................................................................................................................................. 6

3.1 Tutorial matter supplied by Unisa .......................................................................................................................... 6


3.2 Prescribed book ...................................................................................................................................................... 6
3.3 Prescribed software ................................................................................................................................................ 7

4 Additional Reading ........................................................................................................................................................ 7

5 Student Support ............................................................................................................................................................. 7

5.1 Communication with the University ...................................................................................................................... 7


5.2 Contacting the lecturers.......................................................................................................................................... 8
5.3 The COS1512 home page ...................................................................................................................................... 8
5.4 myUnisa ................................................................................................................................................................. 9
5.5 Student support systems ......................................................................................................................................... 9
5.6 Study groups .......................................................................................................................................................... 9

6 Study Programme ........................................................................................................................................................ 10

6.1 Syllabus ................................................................................................................................................................ 10


6.2 Practical work ...................................................................................................................................................... 11
6.3 Workshop ............................................................................................................................................................. 11
6.4 Planning your academic year ............................................................................................................................... 11
6.5 Hints on studying this module .............................................................................................................................. 12

7 Examination ................................................................................................................................................................. 13

7.1 Examination Admission ....................................................................................................................................... 13


7.2 Examination period .............................................................................................................................................. 13
7.3 Year mark............................................................................................................................................................. 14
7.4 Tutorial letter with information on the examination............................................................................................. 14

8 The Assignments .......................................................................................................................................................... 14

Assignment 1 (First Semester).............................................................................................................................................. 17


3 COS1512/101/3/2011

Assignment 2 (First semester) .............................................................................................................................................. 21

Assignment 3 (First Semester and Second Semester) ......................................................................................................... 26

Assignment 1 (Second Semester).......................................................................................................................................... 33

Assignment 2 (Second Semester).......................................................................................................................................... 36

Assignment 3 (Second semester ) ......................................................................................................................................... 40

Appendix A: Installing the Software for COS1512 ............................................................................................................ 41

1. Software for COS1512 ................................................................................................................................................... 41


2. Installing the software .................................................................................................................................................... 42
Method 1 ............................................................................................................................................................................ 42
Method 2 ............................................................................................................................................................................ 42
Uninstalling ........................................................................................................................................................................ 43
3. Using the software .......................................................................................................................................................... 43
Step 1. Starting Dev-C++ .............................................................................................................................................. 43
Step 2. Setting the options ............................................................................................................................................. 43
Step 3. Creating a project............................................................................................................................................... 44
Step 4. Editing a C++ source file ................................................................................................................................... 44
Step 5. Compiling the program ...................................................................................................................................... 45
Step 6. Running the program ......................................................................................................................................... 46
Troubleshooting ............................................................................................................................................................. 46
4. Separate Compilation: Creating Dev-C++ Projects with Multiple Files......................................................................... 47
5. Using the debugger in Dev-C++..................................................................................................................................... 51
What is a debugger? ...................................................................................................................................................... 51
How to use the debugger with a program ...................................................................................................................... 51
The windows that display debug-related information .................................................................................................... 51
How to use the debugger ............................................................................................................................................... 51
6. Printing ........................................................................................................................................................................... 54
Method 1........................................................................................................................................................................ 54
Method 2........................................................................................................................................................................ 54
7. Frequently Asked Questions........................................................................................................................................... 54

Appendix B: How to install the software on Vista .............................................................................................................. 57

Appendix C: How to install the software on Windows 7: .................................................................................................. 60

Appendix D: Source listings of the sample programs in the textbook .............................................................................. 60

Appendix E: Solution to assignment 3 ................................................................................................................................. 63

Appendix F: Study Guide ..................................................................................................................................................... 86


4

1 Introduction
Welcome to COS1512. Up to 2010, this module has been known as COS112V. We hope that you will find this
module interesting and stimulating and that you will increase your knowledge about and your skills in programming
in C++. We shall do our best to make your study of this module successful. You will be well on your way to success
if you start studying early in the semester and resolve to do the assignments properly.

In this module we assume that you have mastered the study material covered in COS1511 (known as COS111U
up to 2010). If you have not passed COS1511 yet, we strongly advise you to consider cancelling your
registration for COS1512 for the following reasons:
• The time constraints of the semester system make it very difficult to master two programming modules at the
same time.
• The study material covered in COS1512 builds on what was done in COS1511. If you have not yet passed
COS1511, you will constantly have to refer back to the COS1511 study material which will make it all the
more time-consuming and difficult to master COS1512.

You will receive a number of tutorial letters during the year. A tutorial letter is our way of communicating with you
about teaching, learning and assessment.

Tutorial Letter 101 contains important information about the scheme of work, resources and assignments for this
module. We urge you to read it carefully and to keep it at hand when working through the study material, preparing
the assignments, preparing for the examination and addressing questions to your lecturers.

Please read Tutorial Letter 301 in combination with Tutorial Letter 101 as it gives you an idea of generally important
information when studying at a distance university and within a particular College.

In Tutorial Letter 101, you will find the assignments and assessment criteria as well as instructions on the preparation
and submission of the assignments. This tutorial letter also provides all the information you need with regard to the
prescribed study material and other resources and how to obtain it. Please study this information carefully and make
sure that you obtain the prescribed material as soon as possible.

We have also included certain general and administrative information about this module. Please study this section of
the tutorial letter carefully.

Right from the start we would like to point out that you must read all the tutorial letters you receive during the
semester immediately and carefully, as they always contain important and, sometimes, urgent information.

We hope that you will enjoy this module and wish you all the best!

2 Purpose and outcomes of this module


COS1512 is one of a number of first-year Computer Science modules offered by the School of Computing at Unisa.

COS1512 focuses on providing an introduction to objects and the object-oriented programming environment using
C++ as programming language. The following topics are covered: file I/O streams as an introduction to objects and
classes; using pre-defined classes such as string and vector; C strings, pointers and dynamic arrays; ADTs
(i.e. user-defined classes including the functions and operators for these classes as well as separate compilation);
recursion; single inheritance and function and class templates.

The specific learning outcomes and assessment criteria for COS1512 appear on the next page:
5 COS1512/101/3/2011

Learning outcomes Assessment Criteria Range Statements


In the form of tasks in study materials,
written assignments, case studies, practical
work and examinations, learners will be
assessed on their ability to

1. The student can · interpret a problem description which Problem statements do not exceed
design a logical specifies the requirements of a 30 lines.
solution to a simple program;
programming · identify all steps necessary to solve a
problem, making problem and order the steps in the
appropriate correct logical sequence;
assumptions. · write down the logical sequence of
operations that a computer should
perform to solve a particular problem;
· apply object-oriented principles during
problem solving.

2. The student can · use the different C++ programming The level is small to medium sized
write C++ program constructs appropriately and correctly, programming problems, the
code, demonstrating in order to implement a solution to a program code not exceeding 200
the principles of good programming problem; lines.
programming style. · write functions and use them in a
program;
· define classes and use object-oriented
principles to implement programming
problems;
· recognise/locate errors in a program and
correct them.

3. The student can · explain the purpose of a particular C++ The context is concepts of the
demonstrate an programming construct and identify programming language required for
understanding of the problem descriptions where they are beginner level computer
theory underlying the applicable. programming.
basic programming · define relevant programming concepts.
concepts.

The specific learning objectives for each chapter in the prescribed book for COS1512 in order to reach the above
learning outcomes are given in more detail in the study guide included in Appendix F of this tutorial letter.

The paragraphs below show where COS1512 fits into the programming modules offered by the School of
Computing:

• COS1511 (known as COS111U up to 2010) deals with the basic concepts of programming, using the
programming language C++. It is aimed at students who have not done any programming before.
• COS1512 introduces the learner to objects and the object-oriented programming environment. It assumes
that you have completed COS1511 or have an equivalent programming qualification. We refer you to Part
2, Section C of the Unisa Calendar.
• COS1521 provides a general background to computer systems.
• INF1511 is an introductory course in Delphi programming.
• COS1501 introduces the mathematics relevant to Computer Science.
6

COS1512 is also a prerequisite for several second-year modules, namely:


• COS2611 focuses on the implementation and use of abstract data types and data structures in an object-
oriented language.
• COS2614 elaborates on the concepts of object-orientation, and the implementation thereof.
• COS2621 introduces students to computer organisation, i.e. the underlying structure of a modern computer.
• COS2633 covers the use of numerical methods in solving scientific and mathematical problems.

3 Tutorial Matter
3.1 Tutorial matter supplied by Unisa
The tutorial matter for this module consists of the following:
• this tutorial letter;
• tutorial letter COSALLF/301/4/2011;
• a CD containing the prescribed C++ software;
• additional tutorial letters, containing additional information or solutions to assignments.

When you register, you will receive an inventory letter containing information about your tutorial matter. See also
the booklet entitled My studies@ Unisa, (which you received with your tutorial matter). Check the study material
that you have received against the inventory letter. You should have received all the items listed in the inventory,
unless there is a statement like “out of stock” or “not available”. If any item is missing, follow the instructions on the
back of the inventory letter without delay.

PLEASE NOTE: Your lecturers cannot help you with missing study material. Please contact the Unisa
Contact Centre at +27 12 429 4104 or 0861 670 411 (RSA only), or +27 11 670 9000 (international calls).

Not all of the above-mentioned tutorial matter will necessarily be available at the time of registration. Tutorial matter
will be despatched to students as soon as it is ready. By following the appropriate links and instructions, tutorial
letters can also be downloaded from the Internet at my.unisa.ac.za or from the School of Computing’s own website
http://osprey.unisa.ac.za.

All information that is made available electronically in the form of tutorial letters will also be sent to you on paper
(except in a very few rare cases). Note that the determining information comes from the paper documents that you
receive. If there is any conflict re for example, dates, prices, times, due dates, assignment numbers, et cetera, refer to
the information published on paper, unless otherwise instructed.

3.2 Prescribed book


The prescribed book for this module is:

Walter Savitch. Problem Solving with C++, 7th edition. Pearson International Edition: Addison-Wesley, 2009,
ISBN 9780321549402.

You may also use the 6th edition of the prescribed book.
7 COS1512/101/3/2011

You are expected to purchase your own copy of the prescribed book. For contact details of official booksellers,
please consult the list of official booksellers and their addresses in My studies@ Unisa. If you have any
difficulties with obtaining books from these bookshops, please contact vospresc@unisa.ac.za.

We will refer to the prescribed book as Savitch.

3.3 Prescribed software


The prescribed software for this module is the MinGW C++ compiler and the DevC++ Integrated Development
Environment (IDE), which are both included in your study package. The prescribed C++ compiler and the IDE are
provided on the CD-ROM that you should have received when you registered. The CD-ROM contains instructions
on how to install the prescribed C++ compiler and the IDE, and how to use the IDE to write, compile and execute
your programs.

These instructions can be accessed from the file index.html on the CD-ROM. There are a number of ways to
view this file. After inserting the CD-ROM into the CD-ROM drive of your computer, do one of the following:
• Click on Run... on the Start menu. In the dialog box that appears, type d:index.html and click on the OK
button.
• Double-click on the My Computer icon on your desktop. In the window that appears, double-click on the CD-
ROM icon (D:). In the window that appears, double click on the file index.html.
• Load Windows Explorer and locate index.html on the CD-ROM drive. Double click on this file.
After doing any one of the above, the file index.html should be loaded into Internet Explorer (or whatever web
browser is installed on your computer). Click on the link for COS1512 and follow the instructions.

Appendix A of this tutorial letter contains more instructions on the use of the C++ software.

4 Additional Reading
You do not have to consult any other textbooks apart from Savitch. However, some of you may want to read more
widely, and consult alternative references. The following useful books are available in the Unisa library. Please note
that the library does not have multiple copies of these books and that only limited waiting lists are kept.

DS Malik. C++ Programming: From Problem Analysis To Program Design. Course Technology, Thomson
Learning, 2009.

HM Deitel and PJ Deitel. C++ How to Program. 6 th edition. Prentice Hall, 2007.

John R. Hubbard. Programming with C++. 2 nd edition. Schaum’s Outlines, 2000.

5 Student Support
5.1 Communication with the University

Lecturers for this module are only responsible for content-related queries about the study material used for
COS1512.

If you need to contact the University about matters not related to the content of this module, please consult the
publication My studies@ Unisa that you received with your study material. This booklet contains information on
how to contact the University (e.g. to whom you can write for different queries, important telephone and fax
8

numbers, addresses and details of the times certain facilities are open).

NB: Always have your student number at hand when you contact the University.

Please note that all administrative enquiries should be directed to the Unisa Contact Centre. Enquiries will then be
channeled to the correct department. The details are as follows:

• Calls (RSA only) 0861 670 411


• International Calls +27 11 670 9000
• Fax number (RSA) 012 429 4150
• Fax number (international) +27 12 429 4150
• E-mail study-info@unisa.ac.za
• Online address: http://my.unisa.ac.za
• Physical address:
University of South Africa
Preller Street
Muckleneuk
Pretoria
City of Tshwane
• Postal Address:
University of South Africa
P O Box 392
Unisa
0003

5.2 Contacting the lecturers


The names of the lecturers will be announced in Tutorial Letter COSALLF/301/4/2011. You can contact us by mail,
e-mail, telephone or fax. If you write us a letter that you want us to reply to, please include your name, student
number and postal address.

The School of Computing can be contacted telephonically at (012) 429 6122. Should you be unable to reach any
of the lecturers for COS1512, please leave a message with one of the secretaries, who can be contacted via the
number given above. Remember to include the module code and your student number with the message.

Students registered for the first semester should send e-mail queries to COS1512-11-S1@.unisa.ac.za, and
students registered for the second semester should send e-mail queries to COS1512-11-S2@.unisa.ac.za. Do not
send e-mail queries directly to a lecturer. Please supply your full name, student number, as well as the module
code in your e-mail. The mail will be forwarded to the lecturer responsible for e-mail correspondence at that
particular time. This is why you need to supply the module code.

Content-related queries should be posted on the COS1512 discussion forum, which is discussed below, rather than
sent to the COS1512 e-mail address. However, if you do not have access to the Internet, you are welcome to send
your query by mail - we will then post it on the COS1512 discussion forum on your behalf, and send you a copy of
the reply we (or a fellow student) gave on the discussion forum.

5.3 The COS1512 home page


The School of Computing has its own web site at http://osprey.unisa.ac.za. Follow the links from there and read the
instructions on personalising the web interface according to your modules. Please read Tutorial Letter
COSALLF/301/4/2011 for more information on the web site.
9 COS1512/101/3/2011

The Osprey home page also has links to discussion forums that allow you to communicate with the lecturers and your
fellow students. Content-related queries and comments should be posted on the discussion forum, and not sent to the
module e-mail address. If no-one else responds adequately, one of the lecturers will. In this way, instead of
responding fifty times to the same question, five hundred students may benefit from a single reply. The lecturers will
monitor the forum, but only respond if they deem it necessary.

Unlike the case when contacting us by e-mail, you are welcome to remain anonymous when posting queries on the
discussion forum - your e-mail identity will be known to the lecturers, but it will appear scrambled in the posting.
You can choose how you want to identify yourself in the discussion forum.

5.4 myUnisa
Unisa also has a web site called myUnisa which you can use to access resources and information at the university.
The myUnisa learning management system is Unisa's online campus that will help you to communicate with your
lecturers, with other students and with the administrative departments of Unisa through the internet. You can also use
myUnisa to submit your assignments and check whether they have been received and marked.

To go to the myUnisa website, start at the main Unisa website, http://www.unisa.ac.za, and then click on the “Login
to myUnisa” link on the right-hand side of the screen. This should take you to the myUnisa website. You can also go
there directly by typing in http://my.unisa.ac.za.

Please consult the publication My studies@ Unisa which you received with your study material for more information
on myUnisa.

5.5 Student support systems


5.5.1 Tutorial support
Unisa offers tutor services for students as additional academic support at the various Unisa regional learning centres
throughout the country. For details of a learning centre near you, please consult Directorate Curriculum and Learning
Development at Tel: +27 12 429 6889. A tutorial is an organised session where students and tutor(s) meet regularly
at a common venue and at scheduled times to discuss course material. The main purpose of the tutorial services is to
facilitate student learning by developing the student’ independent learning skills and assisting students to become
motivated and independent learners. Tutorials help the students to develop and enhance their learning experience and
academic performance through interaction with the tutor and fellow students. Tutorials are not compulsory and
willing students receive tutorial support at a nominal fee. Interested students are advised to consult a learning centre
closest to them to enroll for tutorials. For further information on tutorials consult the brochure My studies @ Unisa.

5.5.2 Other student support systems


For more information on the various student support systems and services available at Unisa (e.g. student counseling,
and language support), please consult the publication My studies@ Unisa that you received with your study material.

5.6 Study groups


It is advisable to have contact with fellow students. One way to do this is to form study groups. The addresses of
students in your area may be obtained from the following department:

Directorate: Student Administration and Registration


PO Box 392
UNISA 0003
Please contact the Unisa Contact Centre 086 167 0411 and ask for the Directorate: Student
Administration and Registration to request contact details of other COS1512 students in your vicinity.
10

6 Study Programme
6.1 Syllabus
In this module we cover the following chapters of Savitch:

Chapter Sections covered

Chapter 1 1.1 and 1.2

Chapter 4 Only 4.6

Chapter 5 Only 5.5

Chapter 6 All sections

Chapter 8 8.1 and 8.3, plus the subsection Converting Between string
Objects and C Strings on page 483 (6th edition) / page 511(7th
edition), thus excluding 8.2 with the exception of the subsection
Converting Between string Objects and C Strings

Chapter 9 All sections excluding the optional subsections in 9.2

Chapter 10 All sections

Chapter 11 All sections, plus Appendixes 7 (p 990 6th edition / p 1044, 7th
edition) and 8 (p993 6th edition / p 1047, 7th edition)
12.1 and 12.2 up to page 699 6th edition / page 743 7th edition,
Chapter 12
thus only the first two pages of 12.2
14.1 and 14.2 up to page 783 6th edition / page 831 7th edition,
Chapter 14
thus excluding 14.3

Chapter 15 Only 15.1, thus excluding 15.2 and 15.3

Chapter 17 All sections

Note that some of the sections (in Chapters 1, 4 and 5) are omitted, because they have already been covered in
COS1511. The other sections that are omitted fall outside the scope of this module.
11 COS1512/101/3/2011

6.2 Practical work


All COS1512 students must have access to a computer running Windows. The computer must have a CD-ROM
drive. Note, however, that we do not support Windows Vista or Windows 7. For the purposes of students who
have to or wish to use Windows Vista or Windows 7, we include instructions on installing the prescribed software on
Windows Vista in Appendix B and instructions on installing the prescribed software on Windows 7 in Appendix C.

All the assignments require extensive practical work on a computer. The examination is a purely written examination
and does not involve doing any work on the computer. There are no compulsory separate practicals that students
need to attend during the year, but a practical workshop will be offered during March (first semester registrations)
and August/September (second semester registrations).

If you do not have a computer at home, gain access to one somewhere else, possibly at work, at a friend’s home, or at
one of Unisa’s computer laboratories. The Unisa computer laboratories in Pretoria and at the regional offices are
available to students for the practical work. You will receive a COSALL tutorial letter explaining where the
laboratories are, the hours during which they are open and the booking procedure.

6.3 Workshop
A practical workshop on objects is offered in Pretoria during March (for first semester students) and
August/September (for second semester students) to assist you in mastering the basic principles regarding objects
before / while attempting assignment 2. The invitation to the workshop (Tutorial Letter 102) includes the questions
you will do in the computer laboratory under assistance from lecturers. The solution to these questions (Tutorial
Letter 103) will be distributed to you after the workshop and be made available online as well.

6.4 Planning your academic year


In overview, the undergraduate academic year is as follows:
First semester Second semester
17 January Academic year begins 11 July Academic year begins

11 February First assignment due 5 August First assignment due

18 March Second assignment due 2 September Second assignment due

May/June Examinations November Examinations

To get going with your studies, do the following:


• Read this tutorial letter (COS1512/101/3/2011) and Tutorial Letter COSALLF/301/4/2011.
• Obtain a copy of the prescribed book.
• Arrange for access to a computer.
• Install the software, referring to Appendix A of this tutorial letter.

We provide two study programmes, one for students who registered for the first semester, and one for students who
registered for the second semester. We recommend that you use the study programmes as a starting point. You will
probably need to adapt this schedule, taking into account your other modules and your personal circumstances. For
example, if the postal service is slow, you may have to move these dates forward.
12

Study programme for first semester registration:


Week Date (Monday) Activity Remark
1 17 Januarie 2011 Install software, Queries on software installation will only be
Study sections in answered up to 31 January
chapters 1, 4 and 5
2 24 Januarie 2011 Study chapter 6
3 31 January 2011 Study chapter 9
4 7 February 2011 Do assignment 1 Due date 11 February 2011
5 14 February 2011 Study chapter 10
6 21 February 2011 Study chapter 11
7 28 February 2011 Study chapter 12
8 7 March 2011 Attend workshop Otherwise, attempt workshop on your own
9 14 March 2011 Do assignment 2 Due date 18 March 2011
10 21 March 2011 Study chapter 8
11 28 March 2011 Study chapter 14
12 4 April 2011 Study chapter 15
13 11 April 2011 Study chapter 17
13 18 April 2011 Do assignment 3 Self-assessment
14 25 April 2011 Revision Study all tutorial matter, including solutions to
15 2 May 2011, up to Revision assignments and workshop. Do examination
examination date paper supplied in examination tutorial letter on
paper.

Study programme for second semester registration:


Week Date (Monday) Activity Remark
1 11 July 2011 Install software, Queries on software installation will only be
Study sections in answered up to 31 July
chapters 1, 4 and 5
2 18 July 2011 Study chapter 6
3 25 July 2011 Study chapter 9
4 1 August 2011 Do assignment 1 Due date 5 August 2011
5 8 August 2011 Study chapter 10
6 15 August 2011 Study chapter 11
7 22 August 2011 Study chapter 12
8 29 August 2011 Attend workshop and Otherwise, attempt workshop on your own
do assignment 2 Due date 2 September 2011
9 5 September 2011 Study chapter 8
10 12 September 2011 Study chapter 14
11 19 September 2011 Study chapter 15
12 26 September 2011 Study chapter 17
13 3 October 2011 Do assignment 3 Self-assessment
14 10 October 2011 Revision Study all tutorial matter, including solutions to
15 17 October 2011, up Revision assignments and workshop. Do examination
to examination date paper supplied in examination tutorial letter on
paper.

6.5Hints on studying this module


Study each chapter in the prescribed book by following these steps:
• Read the corresponding discussion given in the study guide, Tutorial Letter COS1512/501/3/2010.
• Scan the chapter in Savitch to get an overview of what the chapter is about.
13 COS1512/101/3/2011

• Read the chapter again, making sure that you process the information. Relate the text to the given program
listings. You will sometimes have to read a little ahead or read a whole section to make meaningful sense of
a program listing or discussion. Many students merely read the code and not the accompanying text that
explains the code.
• Take the source listing of the sample programs in the textbook, type it into a text file, compile it and execute
it. Observe the output produced. Some of the source listings of the examples can be found on the CD that
you received with your textbook. Appendix D contains instructions on how to gain access to the source
listings.
• Do as many as possible of the self-check questions on a section as you study it. Answers to the self-check
questions are available at the end of each chapter.
• Answer the assignment questions on the chapter. Implement all programming questions on your computer.
• If at all possible, attend the workshop offered in Pretoria.
It is important to realise that the process of learning how to program follows a learning curve: The more programs
you write, the more proficient you will become. Remember that COS1512 has a large practical component and that it
is essential to gain a lot of programming experience. Programming modules also require much more time than other
modules with no practical work. You will probably find that you need to work hard and consistently throughout the
year to develop the necessary programming skills. Plan to spend at least 8 hours per week on this module.

7 Examination
7.1 Examination Admission
Due to regulatory requirements imposed by the Department of National Education the following applies:

To be considered for examination admission in COS1512, a student must submit assignment 1 BEFORE 14 March
2011 (first semester registration) or 22 August 2011 (second semester registration). Note that these dates are
somewhat later than those given on the study program. For your own benefit, try to stick to the dates given in the
study program as far as possible. Please keep a copy of the completed compulsory assignment you submit, so that
you have the necessary proof in the event that the assignment is lost before it can be assessed.

You are expected to submit two assignments during the semester. Since the work in COS1512 is progressive and
later sections build on earlier ones, we suggest that you begin studying as soon as possible and that you do all the
assignments in their proper sequence. Do not leave an assignment until the last minute. You are expected to work
throughout the semester, and falling ill the day before a due date is no excuse not to hand in an assignment. By that
time, you should have completed at least 80% of the assignment, which you should hand in without delay. Due to the
time constraints of the semester system, we cannot extend any submission dates for assignments. The
assignments play an important role in assisting you to master the study material, and also contribute to your year
mark. See section 7.3 for more on the year mark.

Examination admission is finalised during April (first semester) and September (second semester). You will receive
an examination tutorial letter giving more information on the format of the examination paper.

7.2 Examination period


This module is offered in a semester period of fifteen weeks. This means that if you are registered for the first
semester, you will write the examination in May/ June 2011 and the supplementary examination will be written in
October/ November 2011. If you are registered for the second semester you will write the examination in October/
November 2011and the supplementary examination will be written in May/ June 2012.

During the course of the semester, the Examination Section will provide you with information regarding the
examination in general, examination venues, examination dates and examination times.

Make a note of your examination dates and arrange with your employer for leave in good time. Check for clashes on
the examination time-table and, should there be any, discuss them with the Examinations Department immediately.
14

7.3 Year mark


The mark you obtain for assignments will contribute to a year mark. The year mark in turn will contribute 10% of
the final mark you will receive for COS1512, while the mark you obtain in the examination will contribute the
remaining 90% of your final mark.

The weights allocated to the assignments for COS1512 are summarized as follows:

Assignment number Weight


1 (compulsory) 20%
2 80%
3 0% (self-assessment)

To explain how this will work, assume that a student receives 75% for assignment 1, and 80% for assignment 2.
His/her year mark will then be calculated as follows:

Assignment Mark received Weight Contribution to year mark


(Percentage) Mark(%) * Weight(%) Contribution
1 75% 20% 75/100 * 20/100 0.15
2 80% 80% 80/100*80/100 0.64
Total: 0.79

When the total of 0.79 is converted to 10% of the final mark, it will be 7.9%, thus the student’s year mark will be
7.9%. The examination will form the remaining 90% of the final mark for the module. Note that the year mark will
not form part of the final mark for the supplementary examination.

7.4 Tutorial letter with information on the examination


To help you in your preparation for the examination, you will receive a tutorial letter that will explain the format of
the examination paper, set out clearly what material you have to study for examination purposes and give you an
example of a previous examination paper. We advise you, however, not to focus on this examination paper only since
the content of modules and, therefore, examination papers change from year to year. You may, however, accept that
the type of questions that will be asked in the examination will be similar to the questions asked in the assignments.

8 The Assignments
Assignments are seen as part of the learning material for this module. As you do the assignment, study the reading
texts, consult other resources, discuss the work with fellow students or tutors or do research, you are actively
engaged in learning. Looking at the assessment criteria given for each assignment will help you to understand what is
required of you more clearly. The assessment criteria for each assignment correspond to a large extent to the learning
outcomes specified in the study guide (Appendix F) for the study material covered by the assignment.

Two sets of assignments for this year are given at the end of this tutorial letter. The first set of assignments have to
be submitted by students registered for the first semester, and the second set of assignments have to be submitted by
students registered for the second semester. The tutorial matter you have to master in order to complete each
assignment appears in the study programme in Section 6 and at the start of each assignment. The study guide,
Appendix F, contains details on each section. Give yourself enough time to do the assignments properly, bearing in
mind that a single session in front of the computer will not be sufficient to complete a programming task.

The time constraints under the semester system do not allow us to accept late assignments.
15 COS1512/101/3/2011

All the assignments require practical work, i.e. programs that you have to implement on your computer. Submit a
printout of each program, as well as the input and corresponding output for the program. Assignments1 and 2 have to
be submitted by the due date. Assignment 3 is for self-assessment, i.e. you do not have to submit it to Unisa, but will
‘mark’ it yourself by comparing your attempt with the model solution.

PLEASE ADHERE STRICTLY TO THE FOLLOWING RULES:

• Submit only one copy of a specific assignment.


• Use the correct assignment number on your assignment cover, or on myUnisa if you submit your
assignments electronically.
• Do not send assignments directly to any of the lecturers or to the COS1512 e-mail address.
• Assignments must reach UNISA by the due date.
• Check on myUnisa, or contact the Assignments Section to ensure that your assignment was received by
UNISA.
• All programs must be implemented on a computer. Hand-written programs will not be marked. Copy
your programs and output to one word-processing document before you submit.
• NO flash drives or CDs will be accepted!
• Assignments may not be submitted by fax or e-mail.

PLEASE NOTE: Enquiries about assignments (e.g. whether or not the University has received your
assignment or the date on which an assignment was returned to you) must be
addressed to the Unisa Contact Centre at 0861 670 411 (RSA only), or +27 11 670 9000
(international calls) (also see par. 3 above). You might also find information on
myUnisa.

Assignments should be addressed to:

The Registrar
PO Box 392
UNISA
0003

You may submit written assignments and assignments either by post or electronically via myUnisa. For detailed
information and requirements as far as assignments are concerned, see My studies@ Unisa, which you received with
your study package. Follow the instructions given in Tutorial Letter COSALLF/301/4/2011, as well as the brochure
My studies@ Unisa, when submitting your assignments. The URL for myUnisa is: http://my.unisa.ac.za/.
Instructions on how to register to become a myUnisa user, and how you should format your assignments before you
submit them electronically, are given on the web site. The two most important things to remember are that your
submission must consist of a single text file, and that you may submit an assignment only once.

The process to submit an assignment via myUnisa is briefly described below:


• Go to myUnisa at http://my.unisa.ac.za/.
• Log on with your student number and password.
• Choose the correct module (COS1512) in the orange block.
• Click on assignments in the menu on the left-hand.
• Click on the assignment number for the assignment that you want to submit.
• Follow the instructions.

You will receive tutorial letters (201 and 202) discussing each assignment. The solution to assignment 3 is provided
in Appendix E of this tutorial letter. Work through the solutions and make sure that you understand them. When you
receive your marked assignment back from Unisa, compare it to our solutions and make sure you understand the
differences, and also why you lost marks. The assignments serve a very important learning function. Therefore,
even if you do not submit a particular assignment, you should still complete it and compare your solution to ours as
part of your study programme.
16

We may mark only selected questions in the assignment and not the entire assignment. However, as mentioned
before, we discuss each assignment question in a detailed tutorial letter that you will receive after the due date.

When we mark assignments, we comment on your answers. Many students make the same mistakes and
consequently we discuss general problems in the solutions to the assignments. As mentioned before, it is therefore,
important to work through these tutorial letters and to make sure you understand our solutions and where you went
wrong.

The marks you obtain for an assignment are converted to a percentage. If you for instance obtained 25 marks out of
a possible 50 marks for Assignment 1, you received 50% for Assignment 1. For Assignment 1 this percentage in turn
contributes a weight of 20% to the year mark, and for Assignment 2 this percentage contributes a weight of 80% to
the year mark.

If a question is not marked, we will still award some marks if you attempted this question (note that this is not the
way in which questions will be marked in the examination!). We include complete solutions for all questions.

The marks you receive for programming questions will be determined on the following basis:
Question not done 0
Question attempted, but the program does not work at all 30 - 40% of the marks allocated to the question
A good attempt, but there are a few problems with your answer 70 - 80% of the marks allocated to the question
The program works correctly and produces the correct output full marks

Note that not all mistakes are corrected – but we will provide informative comments.

If you do not include the program output, it means there are “a few problems with your answer” and the maximum
you can get is then 70 - 80% of the marks allocated to the question.

You are welcome to work in small groups. However, every member of the group must write and submit his or her
own individual assignment. Thus, discuss the problem, find solutions, etc. in the group, but then do your own
programming and submit your own effort. You will learn to program only if you sit down in front of the computer,
type in the code, debug the program and get it to work. It is unacceptable for students to submit identical
assignments on the basis that they worked together. That is copying (a form of plagiarism) and none of these
assignments will be marked. It is dishonest to submit the work of someone else as your own, i.e. to commit
plagiarism. Such unethical behaviour does not become our profession.

Plagiarism is the act of taking words, ideas and thoughts of others and passing them off as your own. It is a
form of theft which involves a number of dishonest academic activities. Furthermore, you may be penalised or
subjected to disciplinary proceedings by the University.

The Disciplinary Code for Students (2004) is given to all students at registration. Students are advised to study
the Code, especially Sections 2.1.13 and 2.1.4 (2004:3-4). Kindly read the University’s Policy on Copyright
Infringement and Plagiarism as well.
17 COS1512/101/3/2011

Assignment 1 (First Semester)


DUE DATE: 11 February 2011

TUTORIAL MATTER: Chapters 4 to 7 and 9 of the Study Guide (Appendix F)


Chapters 4 (section 4.6), 5 (section 5.5), 6 and 9
(excluding the optional parts of section 9.2) of Savitch both
6th and 7th ed

WEIGHT: 20%

EXTENSION: None

Answer all the questions. Submit all the programs you are required to write, as well as the input and output of all
programs.

Copy the programs and the required input and output to ONE word processor file.
WE DO NOT ACCEPT ANY FLOPPIES, STIFFIES OR CDs.

Question 1
The CheapCell service provider offers a special cell phone contract to students with much cheaper call and sms rates
than the usual contracts. Two options are available. The first option allows cheap talk time for a fixed amount of
R120 per month. The subscriber must then additionally choose a data bundle for R29, R39 or R49. With the second
option the subscriber can choose the cheap talk time amount which can be anything between R75 and R150. An sms
bundle will then be automatically added. The amount of the sms bundle depends on the talk time amount chosen –
for an amount between R75 and R100, a R40 sms bundle is added. For an amount greater than R100, and up to R125,
a R32 sms bundle is added. For an amount greater than R125 and up to R150, a R27 sms bundle is added. A standard
itemised billing amount of only R9.95 is added for both options.

Write a program that will calculate the monthly amount payable. The program must use two overloaded functions,
each named calcPackage. The first function will have two parameters of type double representing the standard
R120 talk time and the amount for the data bundle for option 1 respectively. The second function will have one
double parameter, representing the talk time amount selected for option 2, and the function must then add the
itemised billing amount and the appropriate sms bundle. Both functions must calculate the monthly statement amount
payable and return the value as type double.

The main function should request the user to specify whether he wants the fixed talk time of R120. If he answers yes,
he must be requested to enter the data bundle amount. If he answers no, he must be asked to enter the talk time
amount that he wants. The main function should then call the correct overloaded function and display the monthly
statement amount. Define a double variable and assign the value 120.00 to it to be used for option 1. Do
validation on the input, i.e. make sure that the amount is between R75 and R150, or that a valid data bundle amount
has been entered. Define const variables for the itemised billing amount as well as for the data bundle and sms
bundles amounts.

Question 2
Peter feeds the oldest crocodile at the Johannesburg Zoo. It gets fed a chicken every 10 days. After feeding it on a
specific date, Peter wants to find out if the remaining chickens in the den will be enough to feed the crocodile until
the date that the new batch of chickens will arrive. Write a program that reads in the number of chickens left, and the
18

two dates, and calculate the number of feeds possible before the new batch of chickens arrives. You can assume that
the two dates are in the same year, so only the day and month need to be entered. Use the following definition for the
number of days in each month:

int daysPerMonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

You can ignore leap years. The program must ask for 2 dates – read the day and month of each date separately. The
program must check that the first date entered is the smaller date, using the assert macro. Also verify that the dates
entered are legitimate dates, using the assert macro and the above defined array, e.g. 31 6 is not a valid date. It
must then convert both dates to days and then determine if there are enough chickens left for all the feeds needed
before the second date. Display either the number of feeds for which there won’t be any chickens, or the number of
feeds that can still be made from the current batch of chickens by the time the new batch arrives.

Question 3
A restaurant has a special discount for families of at least 5 members. To get the discount, at least 4 members of the
family must order the special steak dish on the menu, and the family must order at least 2 bottles of wine. The waiter
serving the family must tell the families about the special discount. If the family order qualifies for the discount, the
waiter gets an extra commission which is 3% of the total bill amount. Peter wants to know how much commission he
earned for the evening.

Your task is to write a program that will read the file orders.dat and calculate the number of families that
ordered the special, the extra commission earned by Peter, as well as the average spent per person (including all the
people that he served for the evening).

Each line in the file contains the following data: the number of members in a family, the number of family members
that ordered the special, the number of bottles of wine that the family ordered, and the total bill amount. Create the
file orders.dat containing the orders of all the families that Peter served, as specified below. Declare variables of
type int for the first three values and a variable of type float for the total bill amount.

5 2 2 670.60
6 4 2 890.80
2 2 0 220.00
10 8 1 1340.60
10 4 3 1430.70
4 0 0 460.30
5 3 1 700.00
7 5 2 1100.80
3 1 0 340.80

Using the input file above, your program should create the following results in the output file result.dat:

Number of families that ordered the special: 3


Commission earned from the special meal: R102.67
Average spent per person for the evening: R137.59

Question 4
Numerologists calculate your birth name number by assigning a value to each letter of the alphabet, and adding all
the values together. If the total is more than 9, all the digits get added together, until the result is less than 10, for
example, if the total is 87, 8 and 7 get added together to give 15, and then 1 and 5 get added together to give 6, which
is less than 9. You have to write a program to do this. You must create the file birthName.txt with the names and
surnames separated by commas as is given below. The program must read the file character by character. When an
alphabetical character is read, the program must add its numerical value to a total for the current name and surname.
You can assume that the total will not be greater than 99. All blank characters can be ignored. As soon as a
19 COS1512/101/3/2011

semicolon is read, the program must convert the total for the name to a number less than 10 as explained before.
Then the program must write the total for each name as a character to the output file number.txt, followed by a
semicolon.

Create an input file with the name birthName.txt which contains the following information:

Elizabeth Murray;Molebogeng Mtsweni;Dorothy McMullan;Etienne Cilliers;Allethea


Coppenhagen;Wilhelm Maarschalk;Gertrude Bezuidenhout;Amanda du Toit;Sylvia
Mashishi;Sean Connery;Julia Roberts;

If you program works correctly, it will have the following data in the output file:
4;9;5;6;6;7;5;6;3;7;6;

Ask the user to input the name of the input and output files.

Hint: Use the ASCII values of the alphabetical characters to convert ‘a’ to 1, ‘b’ to 2 etc, as needed for the
calculation. The ASCII value of ‘a’ is 97, the ASCII value of ‘b’ is 98 etc. So ‘a’ – ‘a’ + 1 = 97 – 97
+ 1 will give us the numerical value 1 for ‘a’; ‘b’ – ‘a’ + 1 = 98 – 97 + 1 = 2 will give us the
numerical value of 2 for ‘b’, etc.

Hint: The / and % operators can be used to separate the digits of the total, e.g. if the total is 87, 87 / 10 = 8, which is
the first digit. 87 % 10 = 7, which is the second digit. 8 + 7 = 15, which is still greater than 10, so we repeat the
process: 15 / 10 = 1, giving the first digit. 15 % 10 = 5, giving the second digit, so total = 1 + 5 = 6

Question 5
(a) For each of the following, write a single C++ statement that performs the identified task. Assume that variables
total and score have been defined as type int and that total has been initialised to 84 and score to
12.
(i) Declare two variables fPtr1 and fPtr2 to be pointers to objects of type int.
(ii) Let the pointer fPtr1 point to the int object total.
(iii) Print the address in memory of fPtr1.
(iv) Add the value of score to the value of the object pointed to by fPtr1.
(v) Display the value of the int object pointed to by fptr1.
(vi) Let pointer fPtr2 point to the same location as fPtr1.
(vii) Print the value of the object pointed to by fPtr2.
(viii)Print the contents of fPtr2.

(b) Assume the following declarations:


int a, b, *p, *q;
What is the output of the following C++ code?
q = &a;
*q = 24;
p = &b;
*p = 10;
cout << a << " " << b << endl;
cout << *p << " " << *q << endl;
*p = *q + 10;
cout << *p << " " << *q << endl;
p = new int;
*p = 25;
q = p;
20

cout << *p << " " << *q << endl;


cout << a << " " << b << endl;

Provide a diagram as well to show the final state of memory (similar to Display 9.1 on page 534, Savitch – 7th
edition).
21 COS1512/101/3/2011

Assignment 2 (First semester)


DUE DATE: 18 March 2011

TUTORIAL MATTER: Chapters 10, 11 and 12 of the Study Guide (Appendix


F)
Chapters 10, 11 and 12 (excluding “Creating a
Namespace” on pages 700 to 712 of Savitch 6th ed /
pages 744 -757 Savitch 7th ed)
Appendices 7 and 8 in Savitch
NB: section 6.4 in the 6th edition corresponds to
EXTENTION: section 10.4 in the 7th edition

None

WEIGHT: 80%

Answer all the questions. Submit all the programs you are required to write, as well as the input and output of all
programs.

Copy the programs and the required input and output to ONE word processor file.
WE DO NOT ACCEPT ANY FLOPPIES, STIFFIES OR CDs.

Question 1

Consider the following structure used to keep an address:


struct Address
{
string streetName;
int streetNr;
string city;
string postalCode;
}

Turn the address record into a class type rather than a structure type. The address record class should have private
member variables for all the data. Include public member functions for each of the following:
• a default constructor that initialises the street name and the city to a blank string, the street number to 0 and
the postal code to a string of four 0’s;
• member functions to set each of the member variables to a value given as an argument to the function (i.e.
mutators);
• and member functions to retrieve the data from each of the member variables (i.e. accessors).

Use this class in a program which prints an address. The program should input a value for each of the member
variables and then print an address consisting of the values for the member variables in proper address format. Use
the keyboard to supply input and display the output on the screen. Test your program with the following input:

Street name: Hector Peterson St


Street number: 543
City: Soweto
Postal code: 0192
22

Question 2
The questions below refer to the following class declaration:

#include <iostream>
#include <string>
using namespace std;
class Chequebook
{
public:
Chequebook();
Chequebook(float AccountBalance);
void Deposit (float Amount);
void WithDraw (float Amount);
float CurrentBalance() const;
void Adjust();
private:
float Balance;
};

int main()
{
cout << "Enter the Account balance:";
float amount;
cin >> amount;
Chequebook Chequebook1(amount);
cout << “Account balance: R “ << Chequebook1 << endl;
cout << “Enter amount to deposit:”;
cin >> amount;
Chequebook1.Deposit(amount);
cout << “Balance after deposit: R” << Chequebook1 << endl;
cout << “Enter amount to withdraw:“ ;
cin >> amount;
Chequebook1.WithDraw(amount);
cout << “Balance after withdrawal: R “ << Chequebook1 << endl;
++Chequebook1;
cout << “Balance after adjusting: R” << Chequebook1;
return 0;
}

(a) What is the purpose of the keywords public and private in the class declaration?
(b) What is the purpose of a constructor?
(c) Give implementations of both the default constructor and the second constructor.
(d) Implement the Deposit() and WithDraw() member functions. The Deposit() member function
should increment the member variable Balance with the amount deposited, and the WithDraw() member
function should decrement the member variable Balance with the amount withdrawn.
(e) Implement the CurrentBalance() member function. It should return the current balance of the cheque
book.
(f) The member function Adjust() should increment the member variable Balance by R100. Give an
implementation for this member function.
(g) Overload the stream insertion operator as a friend function. It should write the balance of the account to the
given output stream.
(h) The statement ++Chequebook1; should increment the member variable Balance of Chequebook1 by
R100. Give three different implementations for the overloaded operator ++ to accomplish this:
23 COS1512/101/3/2011

• using the member function Adjust()


• implementing the overloaded operator ++ as a friend function
• implementing the overloaded operator ++ as a member function. Hint: See chapter 11 in the study guide,
Appendix F.
(i) Run your program three times (each time with a different version of the overloaded operator ++; comment the
other two versions out during each run) with the following input:
400
200
300

Question 3
Turn the Chequebook class from question 2 in this assignment into an ADT, so that separate files are used for the
interface and implementation. Use separate compilation to compile the implementation separate from the application
program that tests the ADT.

Question 4
Define a class Team as an ADT that uses separate files for the interface and the implementation. The class represents
a team in the World Cup soccer tournament. This class has the following data members:
string country; // the name of the country for which this team plays
int round; // the round in which the team currently plays
int points; // the points the team has accumulated
int goalsFor; // the goals the team has scored
int goalsAgainst; // the goals scored against the team

The class should contain a default constructor that initializes country to "Country 0"; and round, points,
goalsFor and goalsAgainst to 0. It should also contain an overloaded constructor that accepts five parameters
to set the country, round, points, goalsFor and goalsAgainst member variables to specified values.
The destructor should output "Game Over".

Include accessor functions that return the values stored in each of the member variables of an object of class Team
(i.e. get functions), as well as mutator functions to update each of the member variables of an object of class Team
respectively (i.e. set functions with a parameter to set each member variable to a value specified by the parameter).
The class should also contain a void member function called reset() that resets the member variables of a Team
to values specified by parameters.

In addition the class also have member functions calcGoalDifference() and update(). Member function
calcGoalDifference calculates the difference between the number of goal scored by the team and the number
of goals scored against the team. Member function update updates the points, goalsFor and
goalsAgainst member variables by adding the function’s parameter values to the points for a team as well as to
the goals scored by the team and against the team.

Overload the equality operator== as a friend function for class Team. This function returns true if both the
points member variable and the goal difference of Team1 is identical to that of Team2 and false otherwise.
Use the following prototype:
bool operator==(const Team & Team1, const Team & Team2)

Overload the comparison operator> as a friend function for class Team. This function returns true if the
points member variable of Team1 is bigger than that of Team2; or if the points member variable of Team1
24

is equal to that of Team2 and the goal difference of Team1 is bigger than that of Team2. Otherwise the function
returns false. Use the following prototype:
bool operator>(const Team & Team1, const Team & Team2)

Define an overloaded prefix operator ++ (implemented as a friend function) to return the current instance of the
class Team after incrementing the round member variable by 1.

Overload the stream extraction operator >> and the stream insertion operator << as friend functions for class
Team. The stream insertion operator << should display the country, round, points, goals for and goals against the
team, for a team.

Test your class by writing a program to do the following:


• Use the default constructor to instantiate objects opponent and newOpponent of class Team.
• Use the overloaded constructor to instantiate an object home of class Team by initializing the country
member variable to "South-Africa", the round member variable to 1, the points member variable to 4,
the goalsFor member variable to 6 and the goalsAgainst member variable to 4.
• Reset the opponent object to the following values: “Germany“ 1 4 6 4.
• Use the overloaded insertion operator << to display the values of the member variables of objects home
and opponent.
• Use the overloaded equality operator == to determine whether home and opponent has the same number
of points and the same goal differences. If so, display a message “This is a tie!”. If it is not a tie, use the
overloaded comparison operator > to determine which of home and opponent has the most points; and
then increment the round member variable of the appropriate object (home or opponent) by using the
overloaded prefix operator ++.
• Use the accessor functions to display the values of the country, points and round data members of
both the home and opponent objects.
• Now use the overloaded stream extraction operator >> to obtain values for the member variables for
newOpponent. Use the following values as input: country: “Spain”; round: 1; points: 7; goalsFor: 8; and
goalsAgainst: 2.
• South-Africa has won the match against Spain with 2 goals against 0. Obtain the appropriate values from the
user and update the points, goalsFor and goalsAgainst member variables of South-Africa (home)
and Spain (newOpponent) accordingly. A win counts 3 points and a loss 0.
• Once again, use the overloaded equality operator == to determine whether home and newOpponent has
the same number of points and the same goal differences. If so, display a message “This is a tie!”,
otherwise use the overloaded comparison operator > to determine which of home and newOpponent has
the most points; and then increment the round member variable of the appropriate object (home or
newOpponent) by using the overloaded prefix operator ++.
• Use the accessor functions to display the values of the country, points and round data members of
both the home and newOpponent objects.

Question 5
Overload the ++, > and == operators for objects of class Team in question 4, as member functions. Use
separate compilation and the same program as in question 4 to test these member functions.

Question 6
Overload the stream extraction operator >> for the class Address defined in question 1 to input an object of class
Address either from the keyboard or from a file. Also overload the stream insertion operator << to output an
Address object either to the screen or to a file.

Use separate compilation to convert class Address to an ADT. Then write an application program that requests the
25 COS1512/101/3/2011

user to specify a postal code and uses the overloaded extraction operator >> to extract Address objects one by one
from a file named Address.dat. Compare the postal code supplied by the user to the postal code of each object
extracted from the file. If the postal codes are the same, put the object into an array of Address objects. Assume
that the array will never need to contain more than 20 Address objects. Once all the objects have been extracted
from the file and compared to the user-specified postal code, use the overloaded insertion operator << to display all
the Address objects in the array. Use the following data for the file Address.dat:

Hope St
67
Clarence
0917
Nelson Mandela Drive
643
Pretoria
0181
Albert St
91
Pretoria
0181
Church St
14
Wellington
6734
Main St
907
Soweto
0912
Bushbuck St
89
Polokwane
3452

If the user input 0181 as the postal code, your program should display the two addresses in Pretoria on the
screen.

Enrichment exercise:

Adapt the application program to use a vector instead of an array. It should not be necessary to change the class
interface or implementation file in any way.

This is an additional exercise which you can try once you have studied Chapter 8 (C strings and Vectors) in
Sebesta. You do not have to submit it as part of Assignment 2 and we will not mark it, if you do submit it.
26

Assignment 3 (First Semester and Second Semester)


TUTORIAL MATTER: Chapters 8, 14, 15 and 17 of the Study Guide
(Appendix F)
Chapters 8, 14 (excluding section 14.3), 15 (excluding
sections 15.2 and 15.3) and 17 of Savitch

WEIGHT: None

This assignment is for self-assessment. Do not submit this assignment. The solution to this assignment appears in
Appendix D of this tutorial letter.

Question 1
Write a program that inputs two C string variables, first and last, each of which the user should enter with his
or her name. First, convert both C strings to lowercase. Your program should then create a new C string that contains
the full name in pig latin with the first letter capitalized for the first and last name. The rules to convert a word into
pig latin are as follows:
If the first letter is a consonant, move it to the end and add "ay" to the end.
If the first letter is a vowel, add "way to the end.
For example, if the user inputs "Erin" for the first name and "Jones" for the last name, then the program should create
a new string with the text "Erinway Onesjay" and print it.

Question 2

(a) Write a sorting function that is similar to Display 7.12 in Chapter 7 in Savitch, except that it has an argument for
a vector of ints rather than an array. This function will not need a parameter like number_used as in
Display 7.12, since a vector can determine the number used with the member function size(). This sort
function will have only this one parameter, which will be of a vector type. Use the selection sort algorithm
(which was used in Display 7.12).

(b) Write a program that reads in a list of integers into a vector with base type int. Provide the facility to either
read this vector from the keyboard or from a file, at the user's option. If the user chooses file input, the program
should request a file name. The output is to be a two-column list. The first column is a list of the distinct vector
elements; the second column is a count of the number of occurrences of each element. The list should be sorted
on entries in the first column, largest to smallest. Adapt the sorting function from (a) as necessary.

For example, for the input

-12 3 -12 4 1 1 -12 1 -1 1 2 3 4 2 3 -12


The output should be
N Count
4 2
3 3
2 2
1 4
-1 1
-12 4
27 COS1512/101/3/2011

Question 3

Write a recursive function that returns the sum of the integers between any two integer numbers inclusive. For
example if we want to calculate the sum of integers between the integer numbers 13 and 17 then the sum will be 13 +
14 + 15 + 16 + 17 = 75. This recursive function will expect two integer parameters and will return a double.

Question 4

Examine the code fragment below and answer the questions that follow:

1: #include <iostream>
2: using namespace std;
3:
4: //------------------------------------------
5:
6: class A
7: {
8: private:
9: int x;
10: protected:
11: int getX();
12: public:
13: void setX();
14: };
15:
16: int A::getX()
17: {
18: return x;
19: }
20:
21: void A::setX()
22: {
23: x=10;
24: }
25:
26: //----------------------------------------------
27: class B
28: {
29: private:
30: int y;
31: protected:
32: A objA;
33: int getY();
34: public:
35: void setY();
37: };
38:
39: void B::setY()
40: {
41: y=24;
28

42: int a = objA.getX();


43: }
44:
45: //----------------------------------------------
46:
47: class C: public A
48: {
49: protected:
50: int z;
51: public:
52: int getZ();
53: void setZ();
54: };
55:
56: int C::getZ()
57: {
58: return z;
59: }
60:
61: void C::setZ()
62: {
63: z=65;
64: }

Answer the following questions based on the code fragment given above:
(a) Is line 18 a valid access? Justify your answer.
(b) Is line 32 a valid statement? Justify your answer.
(c) Identify another invalid access statement in the code.
(d) Class C has public inheritance with the class A. Identify and list class C’s private, protected and public
member variables resulting from the inheritance.
(e) If class C had protected inheritance with the class A, identify and list class C’s private, protected and
public members variables resulting from the inheritance.

Question 5
Consider the class definitions below and answer the questions that follow:

class Date{
public:
friend ostream & operator<<(ostream & cout, const Date & d);
Date(int y, int m, int d);
private:
int year, month, day;
};

class Publication {
public:
Publication(const string & p, const Date & d,
const string & t);
Date GetDate( ) const;
string GetPublisher( )const;
29 COS1512/101/3/2011

string GetTitle() const;


private:
string publisher;
Date date;
string title;
};

(a) Implement the Date and the Publication classes.

(b) Code the interface of a derived class Book for which the Publication class is the base class. The Book
class has two additional member variables representing the ISBN number and the author of a book.
Furthermore, the Book class contains member functions getISBN( ) and getAuthor( ) that returns
the ISBN number and the author respectively. The declaration must also include a constructor for the class
Book.

(c) Implement the Book class.

(d) Recode the following interface such that class Magazine, derives from class Publication:
class Magazine{
public:
Magazine(const string & p, const Date & d, int ipy);
int GetIssuesPerYear( ) const;
Date getDate( ) const;
string getPublisher( )const
string GetTitle() const;
private:
int issuesPerYear;
string publisher;
Date date;
string title;
};

(e) Implement the Magazine class.

(f) In a driver program embed code to do the following:


(i) Declare an object B of type Book, with the following details:
publisher: FisherKing
date: 01/01/2000
title: Global Warming
isbn : 123456789
author: Ann Miller

(ii) Output all the details of Book B.

(iii) Declare an object M of type Magazine, with the following details:


publisher: Blue Marlin
date: 02/02/2005
title: The Earth and the Environment
number of issues per year: 12

(vi) Output all the details of Magazine M.

(g) Write a statement to overload operator<< as a friend function to the class Book and insert the
following implementation to your code:

ostream & operator<<(ostream & out, const Book & B)


30

{
out<<B.title<<endl;
out<<B.publisher<<endl;
out<<B.date<<endl;
out<<B.author<<endl;
out<<B.ISBN<<endl;
}

You should obtain the following compiler errors:

In function `std::ostream& operator<<(std::ostream&, const Book&)':


error: `std::string Publication::title' is private
error: `std::string Publication::publisher' is private
error: `Date Publication::date' is private

Suggest two ways to fix this compiler problem.

Question 6
Write a function template for a function that has parameters for a partially filled array and for a value of the base type
of the array. If the value is in the partially filled array, then the function returns the index of the first indexed
variable that contains the value. If the value is not in the array, the function returns -1. The base type of the array is
a type parameter. Notice that you need two parameters to give the partially filled array: one for the array and one for
the number of indexed variables used. Also write a suitable test program to test this function template.

Question 7
Write a template version of a search function for determining whether an array contains a particular value.

Question 8
Study the Matrix class interface and answer the questions that follow:
(Refer to the Notes at end of the question if you are unfamiliar with Matrices)

template<class Object>
class Matrix
{
public:
Matrix( int row = 0, int col = 0 );
void SetValue(Object value, int r, int c);
Object GetValue( int r, int c) const;
int GetRow() const;
int GetCol() const;
void OutPut(ostream & out) const;
private:
vector< vector<Object> > array;
int rows;
int cols;
};

(a) Complete the implementation of the Matrix class where indicated:

template <class Object>


Matrix<Object>::Matrix (int row, int col)
{ rows = row;
cols = col;
array.resize(row);
for (int r = 0; r < row; r++)
31 COS1512/101/3/2011

array[r].resize(col);

//SetValue assigns row r and column c of the Matrix to value


template <class Object>
void Matrix<Object>::SetValue(Object value, int r, int c)
{
//Complete code here
}

//GetValue returns the value in row r and col c of the Matrix


template <class Object>
Object Matrix<Object>::GetValue( int r, int c) const
{
//Complete code here
}

//GetRow returns rows


template<class Object>
int Matrix<Object>::GetRow() const
{
//Complete code here
}

//GetCol returns cols


template<class Object>
int Matrix<Object>::GetCol() const
{
//Complete code here
}

//Outputs the matrix in a tabular format (see Notes for example)


template <class Object>
void Matrix<Object>::OutPut(ostream & out) const
{
//Complete code here
}

//Operator+ is overloaded as a non-friend, non-member function. This


//function adds two Matrices (see Notes for example)
template<class Object>
Matrix<Object> operator+(const Matrix<Object> & x, const Matrix<Object> &
y)
{
//Complete code here
}

b) Test your implementation by coding a main function to perform the following:


(i) Declare three, 2 by 2 integer matrices, M1, M2, and M3;
(ii) Store the following values in M1:
1 2
3 4
(iii) Store the following values in M2:
5 6
7 8
(iv) Store the sum of M1 and M2 in M3 using operator+.
(v) Output all three matrices.
Notes:
32

In mathematics, a matrix (plural matrices) is a rectangular table of numbers or, more generally, a table consisting
of abstract quantities that can be added and multiplied. For example, a 4 by 3 matrix is represented as:

6 6 6
5 3 2
3 1 2
2 7 9
Two matrices can be added if, and only if, they have the same dimensions. (That is, both matrices have matching
numbers of rows and columns.) We define their sum by constructing a third matrix whose entries are the sum of
the corresponding entries of the original two matrices. For example:

4 3 4 2 2 1 6 5 5
1 2 3 + 1 3 2 = 2 5 5
2 2 1 3 4 5 5 6 6
33 COS1512/101/3/2011

Assignment 1 (Second Semester)


DUE DATE: 5 August 2011

TUTORIAL MATTER: Chapters 4 to 7 and 9 of the Study Guide (Appendix F)


Chapters 4 (section 4.6), 5 (section 5.5), 6, and 9
(excluding the optional parts of section 9.2) of Savitch both
6th and 7th ed

WEIGHT: 20%

EXTENSION: None

Answer all the questions. Submit all the programs you are required to write, as well as the input and output of all
programs.

Copy the programs and the required input and output to ONE word processor file.
WE DO NOT ACCEPT ANY FLOPPIES, STIFFIES OR CDs.

Question 1
Peter wants to send a box containing a painting to London. The Post Office sends parcels to London via GlobalMail
or DHL. If GlobalMail is chosen, the cost is R108 per kg if the parcel goes to zone 1 to 3 in London, and R130 per
kg if the parcel goes to zone 4 to 6. If DHL is chosen, the actual weight is compared to the volumetric weight, and
whichever is the higher weight, is used in the calculation. The volumetric weight is calculated by the formula (length
* width * height) / 5000, where length, width and height is the size of the box in cm. The cost per kg for DHL is R70.

Write a program that will calculate the price to be paid for sending a parcel to London. The program must use two
overloaded functions, each named calcPostage. The user must be asked if he wants to use GlobalMail or DHL.
Define a char variable and ask the user to input ‘d’ for DHL or ‘g’ for GlobalMail. If he chooses GlobalMail,
the zone must be requested. The program must validate that the zone is between 1 and 6. If he chooses DHL, the
length, width and height of the box must be requested. The first function will receive two parameters, one of type
double representing the weight of the parcel, and one of type int, representing the zone. The second function will
receive four parameters of type double, representing the actual weight, and the length, width and height of the box
in cms. The second function will first determine whether the actual weight or the volumetric weight is the highest,
before calculating the cost. Both functions will return the cost in a variable of type double. The main function
should then display the total cost. Define const variables where applicable.

Question 2
The principal of a primary school has hired a jumping castle for the September school bazaar. Each child in the
school may jump once for free for 7 minutes. A whistle blows after every 7 minutes at which time the current group
of children gets off and the new group gets on and starts jumping. After 37 whistle blows, all children have jumped
for free. Your task is to write a program that will ask the user to enter a time in 24h00 format representing the time
that the first group started jumping. The user must enter the hours and minutes as two separate values, (i.e. a time of
10h45 will be entered as 10 45). The program then has to calculate the end time, i.e. the time when the last group
has finished their free jump. Use const variable definitions where applicable.
34

Display the start time and the end time in the format hh:mm. Verify that the time entered is a legitimate time, using
the assert macro, e.g. 23 65 01 is not a valid time.

Question 3
The grade 7 pupils of Sunnyside Primary School have three entrepreneur days per month for certain months of the
year. Your task is to write a program that will determine the highest profit amount for each month, as well as the total
profit for the whole year, by reading the data from the input file below. The file contains the names of the months,
followed by the profit amount for the three entrepreneur days for each of the months. Use a variable of type string
to read the month, and three variables of type float to read in the profit amount for the three entrepreneur days per
month. Create an input file profit.dat containing the following data:

Feb 310.60 1200.60 980.70


Apr 1111.20 1345.45 760.40
Jun 666.80 1200.60 1430.90
Aug 1908.10 1040.50 1746.50
Sep 1090.70 770.70 712.30
Nov 432.30 1257.80 1278.40

Create an output file best.dat containing the highest profit for each month, as well as the total profit for the
year.

For the above input file the output file should be:

Feb 1200.60
Apr 1345.45
Jun 1430.90
Aug 1908.10
Sep 1090.70
Nov 1278.40
Total profit for the year: 19244.55

Question 4
Lebo is in grade 4. She typed the following essay about her holiday on the computer. Please help her correct the
following 2 errors - she did not start her sentences with uppercase letters, and she used the character ‘5’ instead of the
letter ‘s’.

Create a file named essay.txt containing the essay below. Write a program that will read the file character by
character, change the first character of the first word of each sentence to an uppercase character, and change all the
‘5’ characters to ‘s’. Write the essay character by character to an output file called correct.txt.

Create an input file called essay.txt with the essay as follows:

my holiday. we went to my aunt’5 farm. 5he ha5 ponie5. 5he taught me to ride
the ponie5, and that wa5 great fun. and 5he ha5 lot5 and lot5 of 5trawberrie5.
we could pick them our5elve5, and we could eat a5 many a5 we wanted. my uncle
let me help him to milk the cow5. it i5 very difficult. the duck in the duck
pond bit my finger when I gave him bread to eat.

Ask the user to input the name of the input and output file.
35 COS1512/101/3/2011

Question 5
(a) For each of the following, write a single C++ statement that performs the identified task. Assume that variables
salary and increase have been defined as type double, and that salary has been initialised as
4500.00 and increase as 475.00.
(i) Declare two variables fPtr1 and fPtr2 to be pointers to objects of type double.
(ii) Let the pointer fPtr2 point to the double object salary.
(iii) Let the pointer fPtr1 point to the double object increase.
(iv) Print the address of the object pointed to by fPtr1.
(v) Print the value of the object pointed to by fPtr2.
(vi) Increase the value of the object that fPtr2 is pointing to, by the value that fPptr1 is pointing to, only
if salary is greater than 4200.00.
(vii) Let the pointer fPtr2 point to the same memory address as fPtr1 is pointing to.
(viii)Print the value of the object that fPtr2 is pointing to.

(b) Use diagrams similar to display 9.1 on p 534 in Savitch – 7th edition to trace the following program and
give the output of the following program.

#include <iostream>
int main()
{
int total1 = 20;
int total2 = 25;
int *ptr1 = &total2;
int *ptr2 = &total1;
cout << *ptr1 << " " << *ptr2 << endl;
ptr1 = ptr2;
*ptr2 -= 5;
cout << *ptr1 << " " << *ptr2 << endl;
cout << total1 << " " << total2 << endl;
return 0;
}
36

Assignment 2 (Second Semester)


DUE DATE: 2 September 2011

TUTORIAL MATTER: Chapters 10, 11 and 12 of the Study Guide (Appendix


F)
Chapters 10, 11 and 12 (excluding “Creating a
Namespace” on pages 700 to 712 of Savitch 6th ed /
pages 744 -757 Savitch 7th ed)
Appendices 7 and 8 in Savitch
NB: section 6.4 in the 6th edition corresponds to
EXTENTION: section 10.4 in the 7th edition

None

WEIGHT: 80%

Answer all the questions. Submit all the programs you are required to write, as well as the input and output of all
programs.

Copy the programs and the required input and output to ONE word processor file.
WE DO NOT ACCEPT ANY FLOPPIES, STIFFIES OR CDs.

Question 1
Consider the following structure used to keep module records:
struct Module
{
string moduleName;
string moduleCode;
string lecturer;
int nrStudents;
}

Turn the module record into a class type rather than a structure type. The module class should have private
member variables for all the data. Include public member functions for each of the following:
• a default constructor that sets the module‘s name and lecturer to a blank string, the module code to seven 0’s and
the number of students to 0;
• an overloaded constructor that sets the member variables to specified values;
• member functions to set each of the member variables to a value given as an argument to the function (i.e.
mutators);
• member functions to retrieve the data from each of the member variables (i.e accessors);

Embed your class definition in a test program. The program should input a value for each of the member variables,
use the overloaded constructor to instantiate a module object and then print all the available information for that
module. Use the keyboard to supply input and display the output on the screen. Test your program with the following
input:
Module name: Introduction to Programming II
Module code: COS1512
Lecturer: Mrs Schoeman
Number of students: 534
37 COS1512/101/3/2011

Question 2
The questions below refer to the class declaration of the class Money, which represents the South African
currency. The class has two integer data members, rands and cents.

#include <iostream>
using namespace std;
class Money
{
public:
Money(); // default constructor
Money(int r, int c); // constructor
~Money(); // destructor
int theRands() const;
int theCents() const;
Money Plus(Money m);
Money operator+ (Money & m);
bool GreaterThan(Money m);
private:
int rands;
int cents;
};

int main()
{
Money m1;
Money m2(15,90);
Money m3(5,15);
m1 = m2.Plus(m3);
cout << m1 << " + " << m2 << " gives " << m1.Plus(m2) << endl;
m1 = m2 + m3;
cout << m2 << " + " << m3 << " gives " << m1 << endl;
if (m2.GreaterThan(m1))
cout << m2 << " is greater than " << m1 << endl;
else
cout << m2 << " is less than " << m1 << endl;
return 0;
}

(a) What is the purpose of the keywords public and private in the class declaration?
(b) What is the purpose of a constructor?
(c) Give implementations of the default constructor and the second constructor, as well as the destructor.
(d) Implement the theRands and the theCents member functions. theRands returns the number of rands
and theCents returns the number of cents.
(d) Implement the Plus()member function. The Plus() member function should add a Money object to the
existing Money object, and return the sum as a Money object.
(e) Implement the overloaded operator+ that adds a Money object to the existing Money object, and returns
the sum as a Money object.
(f) The member function greaterThan() is used to compare two Money objects with each other. Give an
implementation for this member function.
(g) Overload the stream insertion operator as a friend function. It should use the member functions the theRands
and the theCents to write the value of the Money object to the given output stream.
38

(h) The statement if


m1 > m2
cout << m2 << " is greater than " << m1 << endl;
else
cout << m2 << " is less than " << m1 << endl;
displays a message to indicate which value is bigger. Give three different implementations for the overloaded
operator > to accomplish this:
• using the member function greaterThan()
• implementing the overloaded operator > as a friend function
• implementing the overloaded operator > as a member function. Hint: See chapter 11 in the study guide,
Appendix F.
(i) Run your program three times: each time with a different version of the overloaded operator >; comment the
other two versions out during each run using “//”.

Question 4
Define a class Player as an ADT that uses separate files for the interface and the implementation. The class
represents a Player in a video game. This class has the following data members:
string name; // the name of the player
string team; // the team for which this player plays
int level; // the level to which the player has advanced
// to in the game.
int points; // the number of points accumulated

The class should contain a default constructor that initializes name to "Player 0", team to “Team 0”, level to 0
and points to 0. It should also contain an overloaded constructor that accepts four parameters to set the name,
team, level and points to specified values. The destructor should output "Game Over".

Include accessor functions that return the values stored in each of the member variables of an object of class Player
(i.e. get functions), as well as mutator functions to update each of the member variables of an object of class
Player respectively (i.e. set functions with a parameter to set each member variable to a value specified by the
parameter). The class should also contain a void member function called reset() that resets the member
variables of a Player to values specified by parameters.

Overload the equality operator == as a friend function for class Player. This function returns true if the team
member variable of Player1 is identical to that of Player2 and false otherwise. Use the following prototype:
bool operator==(const Player & Player1, const Player & Player2)

Overload the comparison operator> as a friend function for class Player. This function returns true if the
points member variable of Player1 is bigger than that of Player2 and false otherwise. Use the following
prototype:
bool operator>(const Player & Player1, const Player & Player2)

Define an overloaded prefix operator ++ (implemented as a friend function) to return the current instance of the
class Player after incrementing the points by 1. For every 100 points scored, the level is also incremented
by 1. Hint: Use the % (modulus) operator.

A player can request hints while playing the game. For every hint requested, 10 points should be deducted from a
player’s points, and the level (if necessary) at which (s)he plays adapted accordingly. To implement this, define
a void member function requestHint()to simply print a message “Please give me a hint”. (We will not try to
39 COS1512/101/3/2011

supply the hints themselves at this stage or worry about how this will be done.) Member function
requestHint()should then adapt the points and level by calling the overloaded prefix operator-- to return
the current instance of the class Player after decrementing the points by 10 and adapting the level
accordingly. You should also implement the overloaded prefix operator-- as a friend function.
Hint: you can use the this pointer to refer to the calling object in function requestHint() – see Appendix 7 in
Sebesta.

Overload the stream extraction operator >> and the stream insertion operator << as friend functions for class
Player. The stream insertion operator << should display the name, team, level and points of a player.

Question 5
Overload the ==, >, -- and ++ operators for objects of class Player in question 4, as member functions. Use the
same program as in question 4 to test these member functions.

Question 6
Overload the stream extraction operator >> for the class Module in Question 1 to input values for an object of class
Module either from the keyboard or from a file. Also overload the stream insertion operator << to output the data
for a module either on the screen or to a file.

Use separate compilation and write a program that inputs the name of a lecturer. The program should then find all
the modules taught by that lecturer in a file named Modules.dat, and put those objects into an array. Assume that
the file will never contain data for more than 20 modules. Use the array to determine the total number of students
taught by the lecturer, as well as the average number of students per module taught by the lecturer. Display the names
of the modules, the total number of students taught by the lecturer, and the average number of students per module
taught by the lecturer on the screen. Use the overloaded stream extraction operator >> to extract objects from file
Modules.dat. Use the following data for Modules.dat:

Introduction to Programming I
COS1511
Mrs Schoeman
534
Introduction to Programming I
COS1511
Mrs du Plessis
2534
Introduction to Programming II
COS1512
Mrs Schoeman
534
Introduction to Programming II
COS1512
Mrs du Plessis
2534

Enrichment exercise:
Adapt the application program to use a vector instead of an array. It should not be necessary to change the class
interface or implementation file in any way.

This is an additional exercise which you can try once you have studied Chapter 8 (C strings and Vectors) in
Sebesta. You do not have to submit it as part of Assignment 2 and we will not mark it, if you do submit it.
40

Assignment 3 (Second semester )


See page 26 of this tutorial letter.
41 COS1512/101/3/2011

Appendix A: Installing the Software for COS1512


Contents
1. Software for COS1512 ……………………………………………………………………........................ 41
2. Installing the software ………………………………………………………………………..................... 42
3. Using the software…………………………………………….……………………………...................… 43
4. Separate Compilation: Creating DevC++ projects with multiple files ………………....................……… 47
5. Using the debugger in Dev-C++………………………………………………………...................……… 51
6. Printing ……………………………………………………………………………..................…………. 54
7. Frequently Asked Questions …………………………………………………………...................………. 54

This appendix helps you to install and use the recommended software, namely the C++ Integrated Development
Environment (IDE). It covers installing the software, using the IDE and compiler, and some general comments
on troubleshooting some errors. The same instructions, except for section 4, can be found on your CD
DISK2011. It also contains some information regarding CodeMate, which is offered with the textbook.

Note:
On registration you should receive the tutorial matter listed below:
DISK2011: Prescribed software
COS1512/101/2011: First tutorial letter: General information, study programme, exam admission and
assignments

If you have not received all of the above mentioned tutorial matter, please contact our
DESPATCH DEPARTMENT via the Unisa Call Centre at 086 167 0411.

Note that all the COS1512 tutorial letters will also be available on the Internet.

1. Software for COS1512


The first year C++ programming modules COS1511 and COS1512 both use the same prescribed software; a C++
compiler and an Integrated Development Environment (IDE).

The compiler you will be using for these modules is the MinGW port (version 5.0.0) of the Gnu Compiler Collection
(version 3.4.2). The MinGW compiler is designed to work on Windows 95/98/NT/2000/XP platforms. Please note
that Windows Vista is still an unstable operating system, and we cannot guarantee that the MinGW compiler will
work with it. If you want to try to use MinGW with Windows Vista, you will probably have to ask the vendor who
supplied you with Windows Vista to adjust the security settings to get it to work.

The MinGW compiler is distributed under the GNU Public Licence, which means you are free to use, copy, sell or
modify the MinGW compiler. You are not required to register or pay for any of this software. (More information on
MinGW can be found at http://www.mingw.org/).

To access the compiler, you will be using an IDE called Dev-C++ (version 4.9.8.3). Neither the creators of Dev-C++,
nor ourselves, require you to pay for it. (See http://www.bloodshed.net/ if you want more information.)

Please note that you will probably also have problems installing and running Dev-C++ under Windows Vista. We
will not be able to assist you if you attempt to use the prescribed software with Windows Vista.

In COS1512 you will be writing more complicated programs than in COS1511. In particular, later in the course you
will have to write programs that consist of more than one file. To be able to work with more than one file in Dev-
C++, you have to create a project. The Using the software instructions (section 3) therefore explain how to create a
project, and how to make sure that all the files are part of it.
42

Apart from the compiler and the IDE, we have included other useful software and documentation on the CD-Rom.
General purpose utility software (WinZip, Adobe Reader etc.) is in the \utils folder. Extra programming software,
IDEs, sources etc. are in the \src folder. The Dev-C++ help system contains help for Dev-C++. We have added links
to general C++ help. There is also some additional documentation in the \docs folder of the CD-Rom.

We are indebted to Bjarne Stroustrup for a number of his publications on C++. We also thank all of the many
contributors to all of the open source software on the CD-Rom.

2. Installing the software


For COS1512, you will need the Dev-C++ IDE and the MinGW compiler. (This is exactly the same software as for
COS1511. If you installed the software for COS1511 this year, you need not do so again for COS1512. If you
installed a previous version of the IDE and compiler last year, you should uninstall it, and reinstall the new version.)
We give two methods for doing this.

Method 1
Insert the CD into the CD drive and navigate to the CD drive using "Windows Explorer".
Double click on "Index.html" and then click on the second left-hand link “COS1512”.
Then click on the link on the left-hand side called ”2. Installing the software”.
To install the MinGW compiler, follow the blue link “here” in the sentence “To install the MinGW compiler, click
here.“ by clicking on it.
A window will appear containing an icon for the MinGW setup called mingw_gcc3.4.2.exe. Double-click the file /
icon and follow the instructions after that.

During installation, you will be asked to choose the Destination Directory where you want MinGW to be installed.
We recommend that you accept the default destination directory, namely c:\unisa\mingw. If you choose anything
else, you will have to change some settings (Compiler Options) in Dev-C++ which expects the compiler to be stored
in a particular folder.

To install the Dev-C++ IDE, follow the blue link “here” in the sentence “To install the Dev-C++ IDE, click here.” by
clicking on it.

A window will appear containing an icon for the Dev-C++ setup. Double-click the icon and follow the instructions
after that.

During the installation, you will be asked to specify the Destination Directory where you want Dev-C++ to be
installed. We recommend that you choose the default, namely c:\unisa\devcpp.

Method 2
To install the MinGW compiler, do the following:

• Double-click on the "My Computer" icon on your desktop

• Right-click on your CD-Rom icon, and select "Explore";

• Navigate to the \install\mingw folder

• Double-click on the file mingw_gcc3.4.2.exe


During installation, you will be asked to choose the Destination Directory where the compiler must be installed. We
recommend that you accept the default destination directory, namely c:\unisa\mingw.
Then to install the Dev-C++ IDE:

• Navigate to the \install\devcpp folder


43 COS1512/101/3/2011

• Double-click on the file devcppsetup.exe


During the installation, you will be asked to specify the Destination Directory where you want Dev-C++ to be
installed. We recommend that you choose the default, namely c:\unisa\devcpp.

Uninstalling
To uninstall either the compiler or the IDE, use the Add/Remove Programs facility in the Control Panel of
Windows.

3. Using the software


Dev-C++ provides a friendly user interface to the MinGW C++ compiler. In fact, it will not be necessary for you to
work directly with the compiler. You can always do so by means of Dev-C++.

To help you get started we present a short guide to your first "Hello World" program.

As stated in section 1, Software for COS1512, we will be using projects in COS1512 to allow us to write more
complicated programs consisting of more than one file. Although you will only need to write programs consisting of
more files later in the semester, we recommend that you always create a project for your COS1512 programs.

Step 1. Starting Dev-C++


During installation, a shortcut to Dev-C++ should have been placed on the desktop. Double-click it to start Dev-C++.
Otherwise, you can click on the Windows "Start" button and choose "Bloodshed Dev-C++" on the "Programs"
submenu. Alternatively, you can navigate to the folder C:\unisa\devcpp and execute the file devcpp.exe

Step 2. Setting the options


The first time you use Dev-C++, you will be required to choose the language and the user interface theme. We
suggest that you click on OK for each of these options to accept the defaults.
Before you use Dev-C++ to write your first program, you MUST change some of the settings to get it to work
properly:

• Choose "Compiler Options" on the "Tools" menu and click on the "Directories" tab.

• Under the "Binaries" subtab, the path C:\unisa\mingw\bin should appear. If there is some other path
specified, click on the "Delete Invalid" button. Either type the correct path in the edit box at the bottom of
the window, or choose it by clicking on the "..." browse button. Then click on the "Add" button to transfer
the path from the edit box to the list under "Binaries".

• Under the "Libraries" subtab, the path C:\unisa\mingw\lib should appear. If it isn't there, follow the above
instructions to fix it.

• Under the "C Includes" subtab, the path C:\unisa\mingw\include should appear. If it isn't there, follow the
above instructions to fix it.

• Under the "C++ Includes" subtab, no paths should appear. If any are listed, click on the "Delete Invalid"
button.

• Finally, click on the "Programs" tab (at the top of the window). Change the program for "make:" to
mingw32-make.exe. (It must not be gmake.exe.)
You only need to perform the above steps once. You are now ready to write your first C++ program!
44

Step 3. Creating a project


Always start your work by creating a new project. Click on "New | Project" on the "File" menu, or click on the "New
Project" toolbar button. You will be presented dialog with a number of project templates. Click on Console
Application and give a name for your project (eg. First).

After clicking on "OK", you will be required to specify where you want to save the project. We suggest that you
create a separate directory (such as c:\unisa\cos1512) in which you save all your work for a particular module.
Navigate to this folder (if necessary) before clicking on the "Save" button.

Step 4. Editing a C++ source file


When you create a project as explained above, Dev-C++ automatically produces a source file from a template and
opens if for you to edit. Note the Project Browser panel on the left. You can click on the little plus sign next to the
project icon to see what files have been added to the project.

Initially the source file is called Untitled1, so the first thing you should do is give it a name. Do this by choosing
45 COS1512/101/3/2011

"Save" or "Save As" on the "File" menu or by clicking on the "Save" toolbar button. Type the name of the source
code file, eg. first.cpp. (Note that we are using the same name for the project and the source file. The names need not
be the same, however. Later, when you create projects that use multiple files, you will have to use different names.)
Now edit the program to look as follows:

Once you have edited the program, you can save it again by choosing "Save" on the "File" menu or by clicking on
the "Save" toolbar button.

Step 5. Compiling the program


Choose "Compile" on the "Execute" menu or click on the "Compile" toolbar button. A Compile Progress dialog will
be displayed:

Assuming you haven't made any typing mistakes, your program should compile without any errors. If compilation is
successful, the "Cancel" button will change to "Close". Click on the "Close" button. (If there are errors, a Compiler
Output panel will be displayed below the code editor specifying the errors that need to be fixed. See
Troubleshooting below if you are sure there isn't a mistake in your program, but it won't compile correctly.)
46

Step 6. Running the program


Either choose "Run" from the "Execute" menu or simply click on the "Run" toolbar button. If all goes well you
should see a window like the one below. (If you don't see the console window because it flashes and disappears,
choose "Environment Options" on the "Tools" menu and make sure "Console window remains open" is selected.
Then run the program again.)

To return to Dev-C++, press any key.

To create a new program, close your existing project, and open a new one. You should always select Console
Application as the type of project. Windows Applications and Static Libraries are not covered in COS112.

Troubleshooting
If your C++ project won't compile, check the following:

Check that Dev-C++ knows where the MinGW compiler is. In particular, check the following in "Tools | Compiler
Options" under the "Directories" tab:

• C:\unisa\mingw\bin should be added to "Binaries".

• C:\unisa\mingw\lib should be added to "Libraries".

• C:\unisa\mingw\include should be added to "C Includes".

• "C++ Includes" should be empty.


Note that if you installed the MinGW compiler in a directory other than the default (i.e. not in C:\unisa\mingw) then
you will have to change these paths accordingly.
Also check that the correct make program is being used: Click on "Tools | Compiler Options" and then on the
"Programs" tab. Make sure that mingw32-make.exe is specified as the make program (and not gmake.exe).

If you get an error of this type:


C:\unisa\xxxx\Makefile.win [Build Error] * [xxx_private.res] Error 1
during make, retry the make/compile again and the error should disappear.
47 COS1512/101/3/2011

4. Separate Compilation: Creating Dev-C++ Projects with


Multiple Files
This section refers to chapter 12 in the prescribed textbook and chapter 12 in the Appendix F: the Study Guide.
Separate compilation is used to divide a program into parts that are kept in separate files, compiled separately and
then linked together when the program is run. It is typically used to separate the interface and implementation files
of a class. This section describes how to use the DevC++ IDE to set up a project with multiple files, compile and use
these files. We show how to set up a project that uses a user-defined class called TimeType. The class TimeType
will be used in the workshops offered during May and June. The project uses three files:
• TimeType.h, that contains the interface, or definition of the class;
• TimeType.cpp, that contains the implementation of the class; and
• TestTimeType.cpp, a program in which the class TimeType is used and tested.
Note that the header file for the class, TimeType.h is not added to the project. The implementation file for the class,
TimeType.cpp, however, must be added to the project.

How to create a Project: Step by Step for the TimeType class


Step 1(Optional): Create a folder for your project:
Double-click on My Computer on your desktop
Double-click (C:)
Click File → Click New → Click Folder
Name the folder: TimeType

Step 2: Starting Dev-C++


During installation, a shortcut to Dev-C++ should have been placed on the desktop. Double-click it to
start Dev-C++. Otherwise, you can click on the Windows "Start" button and choose "Bloodshed Dev-
C++" on the "Programs" submenu. Alternatively, you can navigate to the folder c:\unisa\devcpp and
execute the file devcpp.exe
Step 3: Creating a Project
Click File → Click New → Click Project
Click Console Application
Name the project: TimeType (indicated by A on Figure 1 below)
Click Ok

Figure 1
48

Navigate to the TimeType folder on your machine (indicated by B on Figure 2)

Figure 2

Click Save (Indicated by C on Figure 2 above)

Step 4: Editing a C++ source file


Type in the contents of TestTimeType.cpp (Indicated by D in Figure 3)

Figure 3

When you create a project as explained above, Dev-C++ automatically produces a source file (Untitled1)
49 COS1512/101/3/2011

from a template and opens it for you to edit. Note the Project Browser panel on the left. You can click on
the little plus sign next to the project icon to see what files have been added to the project.
Click File →Click SaveAs... → save as TestTimeType.cpp

Step 5: Adding an implementation file to the project


Click File → Click New → Click Source File
Dialogue box appears with the message “Add new file to current Project?”
Click Yes
Type in the contents of TimeType.cpp
Click File →Click SaveAs... → save as TimeType.cpp

Step 6: Creating a header file


Click File → Click New →Click Source File
Dialogue box appears with the message “Add new file to current Project ?”
Click No
Type in the contents of TimeType.h
Click File→Click Save As... → save as TimeType.h

Step 7: Cross Check


Your screen should appear similar to Figure 4 below:
E + sign to see what files have been added to the project
F the two files that have been added to the project are listed
G header file TestTimeType.h
H client program TestTimeType.cpp - the only file that contains a main function
I implementation file, TimeType.cpp
Once your project has all these aspects in place, you can now compile your project (Step 8)

Step 8: Compiling and Running your Project


Click Execute → Compile & Run

Trouble Shooting
Error: [Linker error] undefined reference to `TimeType::TimeType()'
Problem: You have not done the implementation for this particular function or you have not added the
implementation file to the project

Special Precautions
Make sure you save your project as you work – Click File →Save All
If your project seems to be running the previous version then Click Execute →Rebuild All
50

H I

G
E
F

Figure 4

Discussion:
The reason why the interface and implementation of a class is often placed in separate files has to do with the idea of
encapsulation. The programmer who uses a class should only need to look at the interface to be able to use it
correctly in a program. For this reason, the interface is placed in a separate (header) file from the implementation.
Also, sometimes you don't want to distribute your source code, but you want other programmers to be able to use the
class(es) that you have defined. In this situation, you can simply provide the compiled (object) code of the
implementation together with the header file (which cannot be compiled separately). Note that when the interface
and implementation of a class is separated, we have to use the scope operator :: together with the name of the class
for the implementations of each of the separated functions.

Note, that we have created the client program (i.e. the program that uses the class) first
(TestTimeType.cpp), then the implementation file (TimeType.cpp) and then the header file
(TimeType.h) file. You may decide the order that best suits you, there is no specific order that is applicable.
Typically the header file is created first, as it is the blue print for the implementation file.
51 COS1512/101/3/2011

5. Using the debugger in Dev-C++


What is a debugger?
A debugger is a software utility that executes program code line by line while keeping track of the variables and the
functions in the program. This step-by-step execution allows you to detect errors in program code. By request, the
utility displays the contents of different variables during execution. The debugger also allows you to stop the
executing program at any point (using breakpoints) in the code, allowing you to examine data at the given point in
the program and also to verify the program code following that point.

Dev-C++ provides a debugger to provide the debugging facility. We will take a step-by-step approach to learn how
to use the debugger in Dev-C++. The Dev-C++ Help file also contains these instructions.

How to use the debugger with a program


There are two ways to use the debugger in Dev-C++.

Option 1: Once you have opened a project file, go to the"Tools | Compiler Options | Settings" tab, then select
"Linker" on the left hand side of the window, choose the "yes" option for the "Generate debugger
information" on the right hand side of the window and click on "OK"

Option 2: On the "Debug" menu select "Debug (F8)". If you do not have debugging information set in your
project as explained in step 1, Dev-C++ will prompt you with a "Confirm Window" asking if you
want to rebuild your program with debugging information enabled. Click on the "Yes" button. Your
project file will then rebuild to include the debugging information.

Now the debugger is ready to be used with the program.

The windows that display debug-related information


There are two windows used to display debug-related information:

1. The window under the "Debug" tab, to the left side of the IDE window (where your program is
displayed).

2. The window under the "Debug" tab, on the bottom section of the IDE window.

These windows will be used in the following sections.

How to use the debugger


Once the debugger has been enabled, you can run it by selecting "Debug" in the "Debug" menu or by selecting the
"Debug" button on the "Debug" tab at the bottom section of the IDE. Remember that you first need to compile a
program before the debugger can be used on the program.

Consider a simple program to calculate the area of two rectangles. We use this program to demonstrate various
aspects of debugging.
#include <iostream>
using namespace std;

int main() {
int length=10;
int width=5;
int area=length*width;

length=5;
width=2;
52

area=length*width;

return 0;
}

Adding breakpoints
Breakpoints are used to pause your program while debugging at a certain line of the program. The purpose of using a
breakpoint is to verify whether the specified line of code is executed and also to verify the variable values at that
point in the program.

To add a breakpoint:

1. First select the line of code where you want to break by simply positioning the text cursor on it. Now go to
the "Debug" menu and click on "Toggle Breakpoint"

OR

2. Click on the gutter (if it is visible on the left of the editor) next to the program line.

OR

3. Right-click on the line of code where you want to break and select "Toggle Breakpoint" on the displayed
menu.

When a breakpoint is added to a program line, the line will be highlighted in red. After choosing the breakpoint, you
can run the debugger. If the debugger has successfully reached the break-pointed line code, the colour of the
highlighted program line will change to blue. We set a breakpoint at line 6 in our example program. The two
screenshots below show this program line with the breakpoint added and the change in colour after the debugger is
run.

Screen shot 1

Screen shot 2

Screen shot 2 shows that execution has reached the break-pointed line of code. Now we can analyse the values of
different variables at the break-pointed line of code. Say for example, we want to verify the value of the variable
length at the break-pointed line of code. To do this, we add watch variables. We can add a watch variable in the
following ways:

1. Click on the "Watch" option of the "Debug" menu. Dev C++ will prompt you with a window named "New
Variable Watch" to enter the variable name that you want to put a watch on. For this example, we type the
variable name length

OR

2. Click on the "Add Watch" button on the "Debug" tab in the bottom section of the Dev-C++ window. The
same prompt to enter the variable name will appear.
53 COS1512/101/3/2011

OR

3. Right-click on the line of code where you want to break and then select "Add Watch" from the displayed
menu. The same prompt to enter the variable name will appear.

The variable name and the content of the variable will be displayed on the left hand side of the Dev C++ window on
the Debug window. The screen shot is given below.

Screen shot 3

In this way, we can add multiple watch variables to verify the contents of these variables. In such a simple program
the debugger may not appear to be particularly helpful, but for long and complex programs such a facility is very
useful.

The watch variables can be deleted by selecting these variables and by using the "Delete" button on the keyboard. To
deselect a breakpoint, go to the line of the program code that has the breakpoint and click on the breakpoint icon on
the gutter of the Editor, or select "Toggle Breakpoint" on an appropriate menu.

Stepping through the program


We can also use the debugger to step through a program to verify if the order of execution of the program is what we
intended. Once the program execution has reached the breakpoint, we can use three different ways of stepping
through the program. These are:

1. Choose "Next Step" on the "Debug" menu OR click on the "Next Step" button available on the "Debug"
tab at the bottom of the IDE window.
Function of "Next Step": The debugger will step one instruction (line of code) in your program.

2. Choose "Step Into" on the "Debug" menu OR click on the "Step Into" button available on the "Debug"
tab at the bottom of the IDE window.
Function of "Step Into": The debugger will step one instruction. If that instruction is a function call it
will step into the function.

3. Choose "Continue" on the "Debug" menu OR click on the "Continue" button available on the "Debug"
tab at the bottom of the IDE window.
Function of "Continue": The debugger will continue the execution of your program until another
breakpoint is reached.
These facilities are useful when debugging loops and functions. They help to verify the order of execution of the
program since each line of the program that is executed is marked blue and hence the lines that are not executed can
be easily detected.

Backtracing
This is used to display all the functions that were executed in a program before the debugger reached the break-
pointed line of code. The function names are displayed under the "Debug | Backtrace" tag on the bottom section of
the IDE window.
54

6. Printing
To print a C++ program, choose the "Print" option on the "File" menu of Dev-C++. If you are submitting an
assignment via myUnisa, simply paste the code of your program into a word processor file.

Printing the output of a program is somewhat trickier. There are (at least) two ways to print the output of a text-based
program (a console application):

Method 1
To print the text from the console window after running your program, you can copy the text to a word processor (an
editor). The steps involved are as follows:
1. Click on the Mark (first) button (after the Font drop-down list) on the toolbar of the console window.

2. Hold the Shift key down and use the arrow keys to mark (highlight) the text as a block.

3. Click on the Copy (second) button to copy the highlighted text to the clipboard.

4. You can now paste it in a word processor (editor) of your choice and print it.

Method 2
Sometimes the above method can be somewhat laborious and problematic, especially if there is so much output that it
scrolls off the top of the screen. In this case, you can send the output directly to the printer (while the program is
running) like this:
1. Open a DOS window (or Command window) and change the directory to where your program is. You will
need to type a DOS command for this, something like cd \unisa\cos112.

2. Check that you are in the correct directory by executing you program. For example, type first.exe and press
<Enter>. If the message "Bad command or filename" is displayed, you are either in the wrong directory or
the name of the executable file is incorrect. You must be able to run your program from the DOS prompt
before proceeding.

3. Make sure that your printer is switched on, is "On-line" and has paper in it, etc.

4. Press <Ctrl+P> to ensure that all the output generated from now on is sent to the printer.

5. Type the name of the executable file, eg. first.exe and press <Enter> to run your program again.

6. Enter any values that the program requires as input.

7. When the program terminates, press <Ctrl+P> again to turn off the printing mode. All the output (and input)
of the program should have been sent to the printer.

8. Now you can close the console window.

Unfortunately, this method won't help if you intend submitting your assignment via myUnisa. You'll have to use
Method 1.

7. Frequently Asked Questions


FAQ 01
The output of my C++ program just flashes on the screen, and then disappears. What can I do?
Answer
Go to the Environment options in the Tools Menu and select “Console Window Remains Open”. Also, ensure that
there are no spaces in the name of the folder/directory in which you store your program, in the program name itself or
in the project name.
55 COS1512/101/3/2011

FAQ 02
My C++ project won't compile, any suggestions?
Answer
Check that Dev-C++ knows where the MinGW compiler is. In particular, check the following in "Tools | Compiler
Options" under the "Directories" tab:
C:\unisa\mingw\bin should be added to "Binaries".
C:\unisa\mingw\lib should be added to "Libraries".
C:\unisa\mingw\include should be added to "C Includes".
"C++ Includes" should be empty
Note that if you installed the MinGW compiler in a directory other than the default (i.e. not in C:\unisa\mingw)
then you will have to change these paths accordingly.

FAQ 03
I get an error “unable to run program file”. What is wrong?
Answer
Check that the filename for the “make:” option in the “Programs” tab under “Tools|Compiler Options” is
mingw32-make.exe. This will usually solve this error.

FAQ 04
Why do I keep getting weird error messages about “path not found” when I try to compile a program?
Answer
After checking all the paths as discussed in FAQs 03 and 04 you can try replacing the contents of
AUTOEXEC.NT (in the system32 folder in Windows XP) with the following:
@echo off
REM AUTOEXEC.BAT is not used to initialize the MS-DOS environment.
REM AUTOEXEC.NT is used to initialize the MS-DOS environment unless a
REM different startup file is specified in an application's PIF.
REM Install CD ROM extensions
lh %SystemRoot%\system32\mscdexnt.exe
REM Install network redirector (load before dosx.exe)
lh %SystemRoot%\system32\redir
REM Install DPMI support
lh %SystemRoot%\system32\dosx
Replace the contents of CONFIG.NT (in the system32 folder in Windows XP) with the following:
REM Windows MS-DOS Startup File
REM
REM CONFIG.SYS vs CONFIG.NT
REM CONFIG.SYS is not used to initialize the MS-DOS environment.
REM CONFIG.NT is used to initialize the MS-DOS environment unless a
REM different startup file is specified in an application's PIF.
REM
dos=high, umb
device=%SystemRoot%\system32\himem.sys
files=40

FAQ 05
I get an error message that says "Undefined reference to _monstartup". What can I do?
Answer
Go to "Project | Project Options | Compiler"
For the "Default compiler" click on "Code profiling" and make sure it is set to "No".
Also check the setting under "Tools | Compiler Options | Settings" for "Code profiling" and make sure it is set to
"No".

FAQ 06
I accidently choose the wrong language during setup and the Dev-C++ IDE appeared in another language. How do I
56

change the language back to English?


Answer
Uninstall Dev-C++, and then search for the hidden devcpp.ini files (there should be 2), delete them and install Dev-
C++ again. This is the easiest way to reset the initial settings.

FAQ07
When I try to compile and run even a simple program, I receive the following error (the directory path for the project
file is C:\unisa\Assignments, the project is Assignment1 and the source file is Question1):
mingw32-make.exe C:\unisa\Assignment1\mingw32-make.exe Circular question <- Question1.o dependency
dropped
C:\unisa\Assignment1\makefile.win [Build error] exe: *** [Question 1] Error 1
Answer
If you get any error message referring to the .o file, open a new project, copy or type the application file into the
untitled file that is created automatically when the project opens, and save it explicitly as a .cpp file. Also save the
implementation file for the class used in the project explicitly as a .cpp file. This usually solves the problem.
57 COS1512/101/3/2011

Appendix B: How to install the software on Vista


1. Install mingw and devcpp as instructed on DISK 2011 (also in Appendix A of this tutorial letter).
2. Run the compatibility wizard by doing the following:
2.1 Click on Start
2.2 Choose Control Panel
2.3 Type ‘compatibility’ in the Search block (top right of Control Panel window)
2.4 Click on ‘Use an older program with this version of Windows’ under Default Programs as
shown below:

2.5 The Program Compatibility Wizard window will appear. Click on Next.
2.6 In the following window, choose ‘I want to locate the program manually’ and click on Next.
2.7 In the window that appears (see below) either browse to find devcpp or type the following path:
C:\unisa\devcpp\devcpp.exe. Then click on Next.
58

2.8 Choose Microsoft Windows XP (Service Pack 2) in the window that follows and click on Next:
2.9 Leave the display settings as is in the following window, and click on Next:
2.10 Click the checkbox to run the program as an administrator in the following window and click on
Next. NB Dev-C++ must be run as an administrator!
2.11 Click on Next to check the compatibility settings in the following window.
2.12 This will take you to Dev-C++ where you can set the initial settings (i.e choose the language and
set up the cache). Once that is done, close Dev-C++ and return to the following window :

2.13 Click on Next


2.14 Choose No in the following window and then click on Next
2.15 Click Finish in the next window to complete the Program Compatibility Wizard.
3. Now you need to create a shortcut to Dev-C++. To set up the shortcut to Dev-C++ follow the steps
below:
3.1 Click on Start
3.2 Choose Computer
3.3 Double-click on C:
3.4 Double-click on unisa
3.5 Double-click on devcpp
3.6 Select ‘devcpp Application’ as shown in the window below
59 COS1512/101/3/2011

3.7 Right-click on ‘devcpp Application’, choose ‘Send To’ in the pop-up menu and then ‘Desktop
(Create shortcut)’ as shown below.

This will place the following shortcut on the desktop:

3.8 Double-click on the shortcut to activate Dev-Cpp.


60

Appendix C: How to install the software on Windows 7


To install the MinGW compiler, do the following:
• Double-click on the "My Computer" icon on your desktop
• Double-click on the CD-Rom icon to open it
• Navigate to the \install\mingw folder
• Right-click on mingw_gcc3.4.2
• Choose Run as administrator
During installation, you will be asked to choose the Destination Directory where the compiler must be installed. We
recommend that you accept the default destination directory, namely c:\unisa\mingw.

Then to install the Dev-C++ IDE:


• Navigate to the \install\devcpp folder
• Right-click on the file devcppsetup
• Choose Run as administrator
During the installation, you will be asked to specify the Destination Directory where you want Dev-C++ to be
installed. We recommend that you choose the default, namely c:\unisa\devcpp.

Now you need to create a shortcut to Dev-C++. To set up the shortcut to Dev-C++ follow the steps below:
• Double-click on the "My Computer" icon on your desktop
Double-click on ”Local Disk C:”
Double-click on “Unisa”
Double-click on the Devcpp folder
Select ‘devcpp Application’ as shown in the window below:
61 COS1512/101/3/2011

Right-click on ‘devcpp Application’ and create the shortcut as shown below:

This will place the following shortcut on the desktop:

Double-click on the shortcut to activate Dev-Cpp.

Remember to change the settings as explained in the section “Using the software” on Disk 2011.
62

Appendix D: Source listings of the sample programs in


the textbook
The source listings of the sample programs in the text book can be found at http://www.aw.com/cssupport. Click
on S under “Author Search”, and then on “Savitch” in the resulting list of authors. Follow the link provided for
the text book. Now double-click on “PSCPP6e-SourceCode.zip” and click on Open. A list of folders, one for
each chapter, will be displayed. Each folder contains the source listings for Displays in the chapter. Display 9.06
for example will be listed as “09-06.cpp”. If you double-click on the file, the source listing will open up in Dev-
C++.
63 COS1512/101/3/2011

Appendix E: Solution to assignment 3


Question 1
Discussion:
In this program we use C-strings to read in the user's first and last name. Both C-strings are then converted to
lowercase before the full name is converted to pig latin.

C-strings use the '\0' character to indicate the end of a C-string. The C-string variables used to store the first and last
names for example are therefore declared as
char first[21], last[21];
to allow 20 characters each for the first and last names as well as one position for the '\0'.

The program uses two functions, convertToLowerCase() to convert a string to lowercase, and pigLatin()
to convert a string to pig latin.

In function convertToLowerCase() we use the null character '\0' as sentinel in the while loop that converts
each character to its lower case.

Program listing:
#include <iostream>
#include <cstring>
using namespace std;

// void convertToLowerCase(char name[])


// Pre: name[] contains a C-string
// Post: name[] has been converted to lower case
void convertToLowerCase(char name[])

//void pigLatin(char name[])


// Pre: name[] contains a C-string
// Post: name[] has been converted to pig latin
void pigLatin(char name[])

int main()
{
char first[21], last[21], newName[41], copyFirst[21], copyLast[21];
cout << "Please enter your first name: ";
cin >> first;
cout << "Please enter your last name: ";
cin >> last;
//make a copy of the first and last name for output purposes
strcpy(copyFirst, first);
strcpy(copyLast, last);
//convert first and last name to lowercase
convertToLowerCase(first);
convertToLowerCase(last);
//convert first and last name to pig latin
pigLatin(first);
pigLatin(last);
//create new string with first and last name in pig latin
strcpy(newName, first);
strcat(newName, " "); //add space between first and last name
strcat(newName, last);
cout << "Dear " << copyFirst << " " << copyLast
<< " in pig latin your name is " << newName << endl;
return 0;
64

void convertToLowerCase(char name[])


{
int i = 0;
while (name[i] != '\0')
{
name[i] = tolower(name[i]);
i++;
}
}

void pigLatin(char name[])


{
char ch;
if ((name[0] == 'a') || (name[0] == 'e') || (name[0] == 'i')
|| (name[0] == '0') || (name[0] == 'u'))
{
name[0] = toupper(name[0]);
strcat(name, "way");
}
else
{
ch = name[0];
for (int i = 0; i <= strlen(name); i++)
name[i] = name[i+1];
name[strlen(name)] = ch;
strcat(name, "ay");
name[0] = toupper(name[0]);
}
}

Input and corresponding output:


Please enter your first name: Erin
Please enter your last name: Jones
Dear Erin Jones in pig latin your name is Erinway Onesjay
Press any key to continue . . .

Question 2
2. (a) Discussion:
We adapted the sorting function to sort a vector from largest to smallest as follows:
The argument was changed from an array of ints to a vector of ints, as can be seen in the function headings:
void sort(vector<int>& v) and
int index_of_largest(const vector<int> v, int start_index)

Note that in order to return the sorted vector, it should be a reference parameter. Also note that since the size of a
vector can be determined with the member function size(), the parameter number_used can be omitted from
both functions.

We want to sort in descending order while the sorting function in Display 7.12 sorts in ascending order. Accordingly,
both function and local variable names that refer to either 'smallest' or 'min' have been changed to
'largest' or 'max'. See for example function index_of_largest below:
int index_of_largest(const vector<int> v, int start_index)
{
int max = v[start_index],
index_of_max = start_index;
65 COS1512/101/3/2011

for (int index = start_index + 1; index < v.size(); index++)


if (v[index] > max)
{
max = v[index];
index_of_max = index;
//max is the largest of v[start_index] through v[index]
}

return index_of_max;
}

While these name changes aid in understanding the sorting order of the sorting function, it does not change the order
in which the vector is sorted from ascending to descending. The crucial change to ensure that the sorting is done in
descending order instead of ascending order, lies in changing the comparison
if (a[index] < min)
in function index_of_largest to
if (v[index] > max)
This change is highlighted in the code section above. The comments have also been adapted to reflect the changed
sorting order.

2. (b) Discussion:

In this question you should have provided a facility to allow the user to specify whether input should be read from a
file, or from the keyboard. Note that when input is read from the keyboard, we indicate the end of file character with
CTRL Z, followed by pressing 'enter':
{ //read input from the console
cout << "Please enter list of values. Press 'enter' "
<< "after each value. Use CTRL Z to end." << endl;
read_vector(list,cin);
}

In function read_vector() inheritance is used so that input can be done both from a file or from the keyboard.
The formal parameter corresponding either to cin (console input) or fin (file input) therefore has to be of type
istream:
void read_vector(vector<int>& v, istream& in_stream);
See Section 10.4 on p 614 in Savitch for more detail.

The distinct elements in the vector are extracted by using a boolean function found() to determine whether or not a
specific element in the original vector (list) occurs in the vector of distinct elements (distinct). Should a
specific element not occur in the vector of distinct elements, it is added to distinct.
//extract distinct elements in list into vector distinct
vector<int> distinct;
for (unsigned int i = 0; i < list.size(); i++)
{
if (!found(list[i], distinct))
distinct.push_back(list[i]);
}

The vector of distinct elements is then sorted, and a third vector (occurrences) with the same number of elements
as distinct is declared and initialised to 0.
//sort vector distinct
sort(distinct);

//declare a vector with distinct.size()elements and initialise


//each to 0
vector<int> occurrences (distinct.size());
66

A function count() is used to count the number of times each distinct element (stored in vector distinct),
occurs in the original list of elements (vector list).
//count occurrences for each element in vector distinct
for (unsigned int i = 0; i < distinct.size(); i++)
occurrences[i] = count(distinct[i], list);

Finally, the corresponding elements in vectors distinct and occurrences are output next to each other to
show the number of times each distinct element occurs in the original list. We show output for input from the
keyboard as well as for input from a file.

Program listing:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>

using namespace std;

void read_vector(vector<int>& v, istream& in_stream);


//to read input values from a stream (file or console) into vector v
bool found(int x, vector<int> v);
//to determine if x occurs in vector v

int count(int x, vector<int> v);


//to count the number of times x occurs in vector v

void sort(vector<int>& v);


//Precondition: number_used <= declared size of the vector v.
//The vector elements v[0] through v[v.size - 1] have values.
//Postcondition: The values of v[0] through v[v.size() - 1] have
//been rearranged so that v[0] >= v[1] >= ... >= v[v.size() - 1].

void swap_values(int& v1, int& v2);


//Interchanges the values of v1 and v2.

int index_of_largest(const vector<int> v, int start_index);


//Precondition: 0 <= start_index < v.size(). Referenced vector elements
//have values.
//Returns the index i such that v[i] is the largest of the values
//v[start_index], v[start_index + 1], ..., v[v.size() - 1].

int main()
{
vector<int> list;
fstream fin;
char answer;
string filename;
int next;
cout << "Do you want to provide input via console or "
<< "using a file(c/f)?";
cin >> answer;
cout << endl;
if (answer == 'f') //read input from a file
{
cout << "Please enter filename: " << endl;
cin >> filename;
67 COS1512/101/3/2011

fin.open(filename.c_str());
if (fin.fail())
{
cout << "Input file opening failed. \n";
exit(1);
}
read_vector(list,fin);
fin.close();
}
else //read input from the console
{
cout << "Please enter list of values. Press 'enter' "
<< "after each value. Use CTRL Z to end." << endl;
read_vector(list,cin);
}

//extract distinct elements in list into vector distinct


vector<int> distinct;
for (unsigned int i = 0; i < list.size(); i++)
{
if (!found(list[i], distinct))
distinct.push_back(list[i]);
}
//sort vector distinct
sort(distinct);

//declare a vector with distinct.size()elements and initialise


//each to 0
vector<int> occurrences (distinct.size());

//count occurrences for each element in vector distinct


for (unsigned int i = 0; i < distinct.size(); i++)
occurrences[i] = count(distinct[i], list);

//output
cout << endl << 'N' << '\t' << "Count" << endl;
for (unsigned int i = 0; i < distinct.size(); i++)
cout << distinct[i] << '\t' << occurrences[i] << endl;

return 0;
}

void read_vector(vector<int>& v, istream& in_stream)


{
int next;
while (in_stream >> next)
{
v.push_back(next);
}
}

bool found(int x, vector<int> v)


{
for (unsigned int i = 0; i < v.size(); i++)
{
if (x == v[i])
return true;
}
return false;
}
68

int count(int x, vector<int> v)


{
int counter = 0;
for (unsigned int i = 0; i < v.size(); i++)
{
if (x == v[i])
counter += 1;
}
return counter;
}

void sort(vector<int>& v)
{
int index_of_next_largest;

for (unsigned int index = 0; index < v.size() - 1; index++)


{//Place the correct value in v[index]:
index_of_next_largest =
index_of_largest(v, index);
swap_values(v[index], v[index_of_next_largest]);
//v[0] >= v[1] >=...>= v[index] are the largest of the original
//vector elements. The rest of the elements are in the remaining
//positions.
}
}

void swap_values(int& v1, int& v2)


{
int temp;
temp = v1;
v1 = v2;
v2 = temp;
}

int index_of_largest(const vector<int> v, int start_index)


{
int max = v[start_index],
index_of_max = start_index;
for (int index = start_index + 1; index < v.size(); index++)
if (v[index] > max)
{
max = v[index];
index_of_max = index;
//max is the largest of v[start_index] through v[index]
}

return index_of_max;
}

Output using console input:


Do you want to provide input via console or using a file(c/f)?c

Please enter list of values. Press 'enter' after each value. Use CTRL Z to
end.
-12
3
-12
4
1
69 COS1512/101/3/2011

1
-12
1
-1
1
2
3
4
2
3
-12
^Z

N Count
4 2
3 3
2 2
1 4
-1 1
-12 4
Press any key to continue . . .

Output using file input:


Do you want to provide input via console or using a file(c/f)?f

Please enter filename:


Q6.dat

N Count
4 2
3 3
2 2
1 4
-1 1
-12 4
Press any key to continue . . .

Question 3
For this question you had to write a recursive function that returns the sum of the integers between any two integer
numbers inclusive. This recursive function expects two integer parameters and returns a double.

Program Listing:
#include <iostream>
using namespace std;

double sum (int m, int n)


{
if (m == n)
return m;
else
return (m + sum ( m + 1, n ) );
}

int main() {
cout << "The sum between 13 and 17 is:";
cout << sum (13,17) <<endl;;
cout << "The sum between 13 and 13 is:";
cout<< sum(13,13) <<endl;
70

cout << "The sum between 13 and 14 is:";


cout<< sum(13,14) <<endl;

return 0;
}

Output:
The sum between 13 and 17 is:75
The sum between 13 and 13 is:13
The sum between 13 and 14 is:27
Press any key to continue . . .

Discussion:

To solve this question, we need to determine the base case and the general case. The base case is when the solution
can be obtained directly.

The base case:


If m is equal to n then we can immediately determine the sum to be m. For example the sum between 13 and 13
would be 13.

The general case on the other hand, is a little harder to deduce:


Consider the following example:
sum(13,17) = 13 + 14 + 15 + 16 + 17

A more general formula can be written as:


sum(m,n) = m+(m+1)+(m+2)+...+(n-2)+(n-1)+n

Recursively:
sum(m,n) = m + sum(m+1,n)

The diagram below represents the recursive calls that will take place if 13 and 17 were passed as parameters to the

sum(13,17) sum(13,17) = 75

since m!=n
return 13 + sum (14,17); return 13 + 62 = 75
step a

sum(14,17) = 62
sum(14,17)

since m!=n return 14 + 48 = 62


return 14 + sum (15,17);
step b

sum(15,17) = 48
sum(15,17)

since m != n return 15 + 33 = 48
return 15 + sum(16,17)
step c

sum(16,17) = 33
sum(16,17)

since m != n return16 +17 = 33


return 16 + sum(17,17)
step d
sum(17,17) = 17

sum(17,17)

since m = n return 17
return 17
step e
71 COS1512/101/3/2011

sum() function. That is, we want to determine the sum between 13 and 17. The diagram shows that each
sum(m,n) induces calls to sum(m+1,n). For instance, since sum(13,17) = 13 + sum(14,17) - this
induces calls to sum(15,17), sum(16,17) and finally sum(17,17). With regard to the diagram below,
recursion works first along the downward arrows until a given point is reached at which an answer is defined (the
base case), and then works along the dashed upward arrows, returning values back to the calling function. For
function sum(), the base case is when m == n.

So eventually the recursive calls will stop at sum(17,17) - because an answer of 17 can be returned.

Hence sum(16,17) is:


sum(16,17) = 16 + 17 = 33 hence sum(16,17) returns 33

So sum(15,17) is:
sum(15,17) = 15 + sum(16,17) = 15 + 33 = 48 hence sum(15,17) returns 48

So sum(14,17) is:
sum(14,17) = 14 + Sum(15,17) = 14 + 48 = 62 hence sum(14,17) returns 62

Therefore sum(13,17) is:


sum(13,17) = 13 + sum(14,17) = 13 + 62 = 75 hence sum(13,17) returns 75

More on Recursion:
Understanding recursion is difficult. Let us consider an everyday example. Suppose you were given a huge bag of
coins and you had to determine how much money was in the bag.
As the bag is large, you prefer not to do the work by yourself. However, you have many willing
friends. You divide the bag of coins into two heaps of coins and ask your friend "Could you please
add up this one heap of coins? I've only given you half, so there's half the work to do”. You, then
give the other half to another friend, and say the same thing. Once both are done, they will give their
answer to you, and you add their results.
Thus, you have broken down the problem into two smaller parts, and asked your friends to do the work.
Now those friends are smart too, so they divide their heap of coins into two parts (now each has two heaps of ¼ of
the size) and each asks two of their friends to help. When their friends are done, they return their answer, and the
result is summed. Now assume that each of their friends does the same and enlists more friends to help and this
process goes on and on. Eventually, there is a heap of only two coins, and these are divided once again and given to
two more friends, and those friends, seeing how silly the problem is now, just tell the first friend the only value on
the coin. There's no need to ask any more friends, because you're down to one coin (this is the base case).
Thus, recursion is all about breaking a problem down, and solving that, and that smaller problem is solved by
breaking it down some more, and trying to solve that. Eventually, you reach an easy solution (the base case), and
return the solution.

Question 4
For this question you had to answer questions based on the following code fragment:

1: #include <iostream>
2: using namespace std;
3:
4: //------------------------------------------
5:
6: class A
7: {
8: private:
9: int x;
72

10: protected:
11: int getX();
12: public:
13: void setX();
14: };
15:
16: int A::getX()
17: {
18: return x;
19: }
20:
21: void A::setX()
22: {
23: x=10;
24: }
25:
26: //----------------------------------------------
27: class B
28: {
29: private:
30: int y;
31: protected:
32: A objA;
33: int getY();
34: public:
35: void setY();
37: };
38:
39: void B::setY()
40: {
41: y=24;
42: int a=objA.getX();
43: }
44:
45: //----------------------------------------------
46:
47: class C: public A
48: {
49: protected:
50: int z;
51: public:
52: int getZ();
53: void setZ();
54: };
55:
56: int C::getZ()
57: {
58: return z;
59: }
60:
61: void C::setZ()
62: {
63: z=65;
64: }

Answer the following questions based on the code fragment given above:

(a) Is line 18 a valid access? Justify your answer?


Yes.
73 COS1512/101/3/2011

The variable x is a private data member of the class A and therefore it can only be accessed by other member
functions and operators of the class A. getX() is a member function of class A and therefore line 18 is a
valid access.

(b) Is line 32 a valid statement? Justify your answer.


Yes.
An object of class A has been included as a protected data member of class B.

(c) Identify another invalid access statement in the code.


Line 42 (int a=objA.getX();) is invalid.
getx() is a protected member function of class A and can therefore only be accessed by other member
functions and operators of the class A and by classes derived from class A.

Class C has public inheritance with the class A. Identify and list class C’s private, protected and public
data members resulting from the inheritance.
With public inheritance, the public and protected members of the base class A are inherited as public and
protected members of the derived class C.
Private data members or member functions resulting from the inheritance: None
Protected data members or member functions resulting from the inheritance: getX()
Public data members or member functions resulting from the inheritance: setX()

If class C had protected inheritance with the class A, identify and list class C’s private, protected and
public data members resulting from the inheritance.
With protected inheritance, public and protected members of the base class become protected
members of the derived class.
Private data members or member functions resulting from the inheritance: None
Protected data members or member functions resulting from the inheritance: setX() and getX()
Public data members or member functions resulting from the inheritance: None

Discussion:
When deriving a class from a public base class, public members of the base class become public members of
the derived class and protected members of the base class become protected members of the derived class. A
base class’ private members are never directly accessible from a derived class, but can be accessed through calls
to the public and protected members of the base class.

When deriving from a protected base class, public and protected members of the base class become
protected members of the derived class. When deriving from a private base class, public and protected
members of the base class become private members of the derived class. Private and protected inheritance
are not “is-a” relationships [Reference: Study Guide Appendix F, chapter 15].

Question 5
For this question you had to answer questions based on the following code fragment:

class Date{
public:
friend ostream & operator<<(ostream & cout, const Date & d);
Date(int y, int m, int d);
private:
int year, month, day;
};

class Publication {
public:
Publication(const string & p, const Date & d,
74

const string & t);


Date GetDate( ) const;
string GetPublisher( )const;
string GetTitle() const;
private:
string publisher;
Date date;
string title;
};

(a) Implement the Date and the Publication classes.

File Name: Date.cpp


#include <iostream>
#include "Date.h"

using namespace std;

Date::Date(int y, int m, int d): year(y), month(m), day(d){}


ostream & operator<<(ostream & out, const Date & d){
out<<d.day<<"/"<<d.month<<"/"<<d.year<<endl;
}

File Name: Publication.cpp


#include <iostream>
#include <string>
#include "Date.h"
#include "Publication.h"

using namespace std;

Publication::Publication( const string & p, const Date & d,


const string & t): publisher(p),date(d),title(t)
{ }

Date Publication::GetDate() const


{
return date;
}

string Publication::GetPublisher()const
{
return publisher;
}

string Publication::GetTitle() const


{
return title;
}

(b) Code the interface of a derived class Book for which the Publication class is the base class. The Book
class has two additional data members representing the ISBN number and the author of a book. Furthermore,
the Book class contains member functions getISBN( ) and getAuthor( ) that returns the ISBN
number and the author respectively. The declaration must also include a constructor for the class Book.

#ifndef BOOK_H
#define BOOK_H
#include "Publication.h"
75 COS1512/101/3/2011

#include "Date.h"
#include <string>

using namespace std;

class Book: public Publication{


public:
Book(const string & p, const Date & d, const string & t, const
string & auth, const string & isbn);
string getAuthor()const;
string getISBN()const;
private:
string ISBN;
string author;

};

#endif

(c) Implement the Book class.

#include "Book.h"
#include <string>
using namespace std;
Book::Book(const string & p, const Date & d, const string & t, const
string & auth, const string & isbn):
Publication(p,d,t),
ISBN(isbn), author(auth){}

string Book::getAuthor()const{
return author;
}

string Book::getISBN() const {


return ISBN;
}

Note, the constructors of the Book class call the Publication constructor (shown in bold) in their initializer lists.
Constructing a derived class object by first constructing its inherited portion is a standard practice. (For a complete
discussion on this subject - refer to pages 865-868 of Savitch, under the section entitled "Constructors in Derived
Classes").

(d) Recode the following interface such that class Magazine, derives from class Publication:
#ifndef MAGAZINE_H
#define MAGAZINE_H
#include "Publication.h"
class Magazine: public Publication {
public:
Magazine(const string & p, const Date & d, const string & t, int ipy);
int GetIssuesPerYear( ) const;

private:
int issuesPerYear;
};
#endif

Note how the class requires less code due to inheritance.

(e) Implement the Magazine class.


76

#include "Magazine.h"

Magazine::Magazine(const string & p, const Date & d, const string & t,


int ipy):Publication(p,d,t), issuesPerYear(ipy)
{}

int Magazine::GetIssuesPerYear()const{
return issuesPerYear;
}

(f) For this question you had to design a driver program to test your classes:

#include <iostream>
#include "Date.h"
#include "Publication.h"
#include "Book.h"
#include "Magazine.h"

using namespace std;


int main(){
Date date1(2000,1,1);
Date date2(2005,2,2);

Book B("FisherKing", date1, "Global Warming", "123456789",


"Ann Miller");
cout<<B.GetTitle()<<endl;
cout<<B.GetPublisher()<<endl;
cout<<B.GetDate()<<endl;
cout<<B.getAuthor()<<endl;
cout<<B.getISBN()<<endl;
Magazine M("Blue Marlin", date2,
"TheEarth and the Environment",12);
cout<<M.GetTitle()<<endl;
cout<<M.GetPublisher()<<endl;
cout<<M.GetDate()<<endl;
cout<<M.GetIssuesPerYear()<<endl;

return 0;
}

(g) Write a statement to overload operator<< as a friend function to the class Book and insert the following
implementation to your code:

ostream & operator<<(ostream & out, const Book & B){


out<<B.title<<endl;
out<<B.publisher<<endl;
out<<B.date<<endl;
out<<B.author<<endl;
out<<B.ISBN<<endl;
}

You should obtain the following compiler errors:

In function `std::ostream& operator<<(std::ostream&, const Book&)':


error: `std::string Publication::title' is private
error: `std::string Publication::publisher' is private
error: `Date Publication::date' is private

Suggest two ways to fix this compiler problem.


77 COS1512/101/3/2011

Method 1: Use the accessor functions as shown below:


ostream & operator<<(ostream & out, const Book & B){
out<<B.GetTitle()<<endl;
out<<B.GetPublisher()<<endl;
out<<B.GetDate()<<endl;
out<<B.getAuthor()<<endl;
out<<B.getISBN()<<endl;
}

Method 2: Change the member variables of Publication into protected access. As they are now
protected and not private they become accessible to the derived class Book. The protected members of
Publication become protected members of Book. They now can be directly accessed by member functions and
friend functions of Book.

class Publication {
public:
Publication(const string & p, const Date & d, const string & t);
Date GetDate( ) const;
string GetPublisher( )const;
string GetTitle() const;
protected:
string publisher;
Date date;
string title;
};

Full Programming Listing:


File name: Date.h
#ifndef DATE_H
#define DATE_H
#include <iostream>

using namespace std;


class Date{
public:
friend ostream & operator<<(ostream & cout, const Date & d);
Date(int y, int m, int d);
private:
int year, month, day;
};

#endif

File name: Date.cpp


#include <iostream>
#include "Date.h"

using namespace std;

Date::Date(int y, int m, int d): year(y), month(m), day(d){}


ostream & operator<<(ostream & out, const Date & d){
out<<d.day<<"/"<<d.month<<"/"<<d.year<<endl;
}

File name: Publication.h


#ifndef PUBLICATION_H
#define PUBLICATION_H
#include <string>
78

#include "Date.h"

using namespace std;


class Publication {
public:
Publication(const string & p, const Date & d, const string & t);
Date GetDate( ) const;
string GetPublisher( )const;
string GetTitle() const;
private:
string publisher;
Date date;
string title;
};

#endif

File name:Publication.cpp
#include <iostream>
#include <string>
#include "Date.h"
#include "Publication.h"
using namespace std;

string Publication::GetTitle() const{


return title;
}
Publication::Publication( const string & p, const Date & d, const string &
t): publisher(p),date(d),title(t){}

Date Publication::GetDate() const{


return date;
}

string Publication::GetPublisher()const{
return publisher;
}

Filename: Book.h
#ifndef BOOK_H
#define BOOK_H
#include "Publication.h"
#include "Date.h"
#include <string>

using namespace std;

class Book: public Publication{


public:
friend ostream & operator << (ostream & out, const Book & B);
Book(const string & p, const Date & d, const string & t, const string &
auth,const string & isbn);
string getAuthor()const;
string getISBN()const;
private:
string ISBN;
string author;
};

#endif
79 COS1512/101/3/2011

Filename: Book.cpp
#include "Book.h"
#include <string>
using namespace std;

Book::Book(const string & p, const Date & d, const string & t, const
string & auth, const string & isbn):
Publication(p,d,t),
ISBN(isbn), author(auth){}

string Book::getAuthor()const{
return author;
}

string Book::getISBN() const{


return ISBN;
}
ostream & operator<<(ostream & out, const Book & B){
out<<B.GetTitle()<<endl;
out<<B.GetPublisher()<<endl;
out<<B.GetDate()<<endl;
out<<B.getAuthor()<<endl;
out<<B.getISBN()<<endl;
}

Filename: Magazine.h
#ifndef MAGAZINE_H
#define MAGAZINE_H

#include "Publication.h"
class Magazine:public Publication {
public:
Magazine(const string & p, const Date & d, const string & t, int
ipy);
int GetIssuesPerYear( ) const;
private:
int issuesPerYear;
};
#endif

Filename: Magazine.cpp
#include "Magazine.h"

Magazine::Magazine(const string & p, const Date & d, const string & t, int
ipy):Publication(p,d,t), issuesPerYear(ipy)
{}

int Magazine::GetIssuesPerYear()const
{
return issuesPerYear;
}

Filename: Test.cpp
#include <iostream>
#include "Date.h"
#include "Publication.h"
#include "Book.h"
#include "Magazine.h"
80

using namespace std;


int main(){
Date date1(2000,1,1);
Date date2(2005,2,2);

Book B("FisherKing", date1, "Global Warming", "123456789",


"Ann Miller");
cout<<B.GetTitle()<<endl;
cout<<B.GetPublisher()<<endl;
cout<<B.GetDate()<<endl;
cout<<B.getAuthor()<<endl;
cout<<B.getISBN()<<endl;
Magazine M("Blue Marlin", date2, "TheEarth and the Environment",12);
cout<<M.GetTitle()<<endl;
cout<<M.GetPublisher()<<endl;
cout<<M.GetDate()<<endl;
cout<<M.GetIssuesPerYear()<<endl;

return 0;
}

Question 6
Discussion:
For this question, you had to define a function template that searches an array for a specific value and returns the
index of the first occurrence of that value. The template should have parameters for a partially filled array and for a
value of the base type of the array. If the value is in the partially filled array, then the function returns the index of
the first occurrence of that value, otherwise the function returns -1. The base type of the array is a type parameter.

Function templates are special functions that can operate with generic types. This allows us to create a function
template whose functionality can be adapted to more than one variable type or class without repeating the code for
each type. For instance, with this program we used the same search() function for an array of doubles (
Doubles), an array of characters (Characters) and an array of integers (Integers). Without templates we
would have had to write a separate search() function for each type of array. (Section 17.1 of Savitch has detailed
explanations on the declarations of function templates.)

A template parameter is a special kind of parameter that can be used to pass a type as a parameter. The function
templates can use these parameters as if they were regular types. The declaration for the search() function
combined template parameters with a defined parameter type:
template<class T>
int search( T array[], int n, T target)

Be cautious when using template parameters - you cannot apply it without considering all the implications.
For example:
template<class T>
int search( T array[], T n, T target)
* This does not make sense as we want to run a loop n number of times to search the array for our target
element - n must certainly be of type integer. Hence it does not make sense within this context to declare n as a
template parameter.

Program Listing:
#include <iostream>

//Precondition: the array base type must have operator== defined,


//&& n <= declared size of the array argument.
//Postcondition: Function returns index of the first
//occurrence of target in array. If target is not in the
//array, the function returns -1
81 COS1512/101/3/2011

using namespace std;

template<class T>
int search( T array[], int n, T target)
{
for ( int i = 0; i < n; i++ )
{
if (array[i] == target)
return i;
}
return -1;
}

int main(){
char Characters[14] = { 'M', 'A', 'P', 'C','E' };
int Integers[14] = { 1, 4, 3, 5, 3, 6, 8, 9, 10, 7};
double Doubles[14] = {2.99,8.77,4.88,6.44,3.45};

cout << " C found at index "


<< search( Characters,5,'C')
<< " in array of characters"
<< endl;
cout << " c found at index "
<< search( Characters,5,'c')
<< " in array of characters"
<< endl;
cout << " 5 found at index "
<< search( Integers, 10, 5)
<< " in array of integers"
<< endl;
cout << " 3.45 found at index "
<< search( Doubles, 10, 3.45)
<< " in array of doubles"
<< endl;
}

Output:
C found at index 3 in array of characters
c found at index -1 in array of characters
5 found at index 3 in array of integers
3.45 found at index 4 in array of doubles
Press any key to continue . . .

Question 7
Discussion:
For this question, you had to specify a template version of a search function to determine whether an array contains a
particular value. Here only two of the parameters had to be template type parameters, namely the array type and the
target (i.e. the element being searched). As discussed, with the previous question, it does not make sense to alter the
other parameters into template type parameters. We also included a templatized Output() function to output an
array of any type and to call the search() algorithm to further promote reuse.

Program Listing:
#include <iostream>
#include <string>
using namespace std;
82

//Precondition: the array base type must have operator== defined,


//&& n <= declared size of the array argument.
//Postcondition: Function returns true at the first
//occurrence of target in array. If target is not in the
//array, the function returns false

template<class T>
bool search( T array[], int n, T target)
{
for ( int i = 0; i < n; i++ ){
if (array[i] == target)
return true;
}
return false;
}
//Precondition: the array base type must have operator<< defined,
//&& n <= declared size of the array argument.

template <class T>


void Output(T array[], int n, T target, string s){
if (search(array,n,target))
cout << s << "does contain " << target <<endl;
else
cout << s << "does not contain " << target <<endl;
}

int main(){
char Characters[14] = { 'M', 'A', 'P', 'C','E' };
int Integers[14] = { 1, 4, 3, 5, 3, 6, 8, 9, 10, 7};
double Doubles[14] = {2.99,8.77,4.88,6.44,3.45};

Output( Characters,5,'C', "Array Characters ");


Output( Characters,5,'c', "Array Characters ");
Output( Integers, 10, 5 , "Array Integers ");
Output( Integers, 10, 15 , "Array Integers ");
Output( Doubles, 10, 3.45, "Array Doubles ");
Output( Doubles, 10, 3.455, "Array Doubles ");
}

Output:
Array Characters does contain C
Array Characters does not contain c
Array Integers does contain 5
Array Integers does not contain 15
Array Doubles does contain 3.45
Array Doubles does not contain 3.455
Press any key to continue . . .

Question 8

For this question, you had to implement the operations of a Matrix class template.
(a) The code to be inserted shown in bold.

Discussion:

Until now, we have placed the definition of the class (in the header file) and the definition of the member functions
(in the implementation file) in separate files. However this does not work with class templates. As shown below both
83 COS1512/101/3/2011

the interface and implementation are within the header file Matrix.h

File name: Matrix.h


#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
template<class Object>
class Matrix
{
public:
Matrix( int r = 0, int c = 0 );
void SetValue(Object value, int row, int col);
Object GetValue( int row, int col) const;
int GetRow() const;
int GetCol() const;
void OutPut(ostream & out) const;
private:
vector< vector<Object> > array;
int rows;
int cols;
};

template <class Object>


Matrix<Object>::Matrix (int row, int col){
rows = row;
cols = col;
array.resize(row);
for (int r = 0; r < row; r++)
array[r].resize(col);

template <class Object>


void Matrix<Object>::SetValue(Object value, int row, int col){
array[row][col] = value;
}

template <class Object>


Object Matrix<Object>::GetValue(int row, int col) const{
return array[row][col];
}

template<class Object>
int Matrix<Object>::GetRow() const{
return rows;
}

template<class Object>
int Matrix<Object>::GetCol() const{
return cols;
}

template <class Object>


void Matrix<Object>::OutPut(ostream & out) const{
for (int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
84

out<<array[r][c]<<'\t';
}
cout<<endl;
}
}

template<class Object>
Matrix<Object> operator+(const Matrix<Object> & x,
const Matrix<Object> & y){
int xrow = x.GetRow();
int xcol = y.GetCol();
assert( xrow == y.GetRow() && xcol == y.GetCol());
Matrix<Object> temp(xrow,xcol);
for (int r = 0; r < xrow; r++){
for(int c = 0; c < xcol; c++){
Object sum = x.GetValue(r,c) + y.GetValue(r,c);
temp.SetValue(sum, r, c);
}
}
return temp;
}

#endif

(b) For this question you had to write a test program for your Matrix class:

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

int main() {
Matrix<int> M1(2,2);
Matrix<int> M2(2,2);

M1.SetValue(1,0,0);
M1.SetValue(2,0,1);
M1.SetValue(3,1,0);
M1.SetValue(4,1,1);

M2.SetValue(5,0,0);
M2.SetValue(6,0,1);
M2.SetValue(7,1,0);
M2.SetValue(8,1,1);

Matrix<int> M3(2,2);
M3 = M1 + M2;

M1.OutPut(cout); cout<<endl;
M2.OutPut(cout);cout<<endl;
M3.OutPut(cout);cout<<endl;

return 0;
}

Output Produced:
1 2
3 4

5 6
85 COS1512/101/3/2011

7 8

6 8
10 12

Press any key to continue . . .

Note:
As shown above - we also have the possibility to write class templates, so that a class can have members that use
template parameters as types. C++ class templates are used where we have multiple copies of code for different data
types with the same logic. If a set of functions or classes have the same functionality for different data types, they
become good candidates for being written as templates. C++ class templates are ideal for container classes (a class of
objects that is intended to contain other objects). Examples of container classes will be the STL classes like vector
(chapter 8, Savitch), and list. Once the code is written as a C++ class template, it can support all data types. (See
section 17.2, Savitch for full explanations on Class Templates.) For instance the Matrix template above can
accommodate a Matrix of any type, be it strings, doubles, ints, etc.

Savitch limits his discussion to popular member functions of the STL vector class, such as push_back (page 513),
size (page 513), capacity (page 517), reserve (page 517) and resize (page 518). However there are other
member functions such as:
empty which returns true if the vector is empty and false otherwise
pop_back which removes the last element of a vector
back which returns the last element of the vector
86

Appendix F: Study Guide for COS1512


Contents
Introduction 87

Guide to the prescribed book 89

Chapter 1: Introduction to Computers and C++ Programming 89


Chapter 4: Procedural Abstraction and Functions That Return a Value 92
Chapter 5: Functions for All Subtasks 93
Chapter 6: I/O Streams as an Introduction to Objects and Classes 94
Chapter 8: Strings and Vectors 97
Chapter 9: Pointers and Dynamic Arrays 99
Chapter 10: Defining Classes 100
Chapter 11: Friends, Overloaded Operators, and Arrays in Classes 102
Chapter 12: Separate Compilation and Namespaces 112
Chapter 14: Recursion 114
Chapter 15: Inheritance 116
Chapter 17: Templates 120
87 COS1512/101/3/2011

Introduction
Welcome to COS1512, an introduction to objects and the object-oriented programming environment. This study
guide accompanies the prescribed book for COS1512:

Walter Savitch. Problem Solving with C++, 7th edition. Pearson Education, Inc, 2009.

We will refer to the prescribed book as Savitch.

Note that this study guide refers to the 7th edition of Savitch throughout. If you are using the 6th edition of Savitch,
please contact the module leader via e-mail to request a copy of the study guide for the 6th edition of Savitch.

Tutorial Letter 101 specifies the sections in Savitch that are covered in COS1512. We repeat them here for your
convenience. Some of the work in the prescribed book is also covered by COS1511, and therefore only certain
sections and chapters are covered in COS1512. The path that COS1512 follows through the prescribed book can be
outlined broadly as follows:
Section 1.2 (p42 - 48) in chapter 1 provides a general overview over programming and problem-solving with a brief
introduction to object-oriented programming. Though most of chapters 4 and 5 have been covered in COS1511,
section 4.6 (overloading functions) and section 5.5 (the assert macro) are included to ensure that students have the
necessary background knowledge to understand and implement object-oriented programming. Chapter 6 uses file
I/O streams as an introduction to objects and classes, and teaches students how to use pre-defined classes. Chapter 8
builds on using pre-defined classes by introducing the standard class string. Chapter 8 also covers C strings and
provides a preview of the Standard Template Library (STL) with the vector class. Chapter 9 further adds to the
background knowledge necessary to understand and implement classes and objects by discussing pointers and
dynamic arrays. In Chapter 10 students learn how to define their own classes in order to create an abstract data type
(ADT). Chapter 10 also covers inheritance briefly in order to make students aware of this concept. Chapter 11
continues to teach more techniques for defining functions and operators for classes. Chapter 12 covers separate
compilation, to allow placing the interface and implementation of an ADT in files separate from each other and
separate from the programs that use the ADT. In Chapter 14 recursion is introduced. In Chapter 15 single
inheritance, i.e. deriving one class from another is covered. In Chapter 17 function and class templates are covered,
which will allow students to understand and use the STL.

The specific learning outcomes and assessment criteria for COS1512 are provided in section 2 of Tutorial Letter 101.
These specific learning outcomes translates to learning objectives for the study material which should be achieved in
order to realise the learning outcomes. This study guide specifies the learning objectives for each section in the
prescribed book.
88

The discussion of each chapter in Savitch given in this tutorial letter typically includes these subsections:
• Overview
• Learning Objectives.

The Overview indicates the main issues addressed in each chapter. The Learning Objectives of each chapter are the
skills you should acquire when mastering the content of the chapter. You will be tested on these skills in the
examination. These objectives can be achieved by doing the self-test exercises and the assignments, implementing
the examples given in the textbook and doing some additional exercises.

Supplementary information is given where we feel that the explanation given in the prescribed book is inadequate.
Please read these sections carefully, as you may not be able to complete the assignments without the additional
information.
89 COS1512/101/3/2011

Guide to the prescribed book

Chapter 1: Introduction to Computers and C++ Programming


Savitch: Section 1.1 p39 Compilers
Section 1.2 p42-48 Programming and Problem-Solving

1.1 Overview
Much of what is covered in this chapter you probably have encountered somewhere in your programming studies up
to now. We want to bring two specific aspects in this chapter to your attention: the process of compiling a C++
program, and the concept of object-oriented programming. Though you will not be examined on this chapter as such,
it serves as a brief orientation to the concepts covered in this course.

1.2 Learning Objectives


After having read sections 1.1 and 1.2, you should
• be aware of what the process of compiling and linking a C++ program entails;
• have a broad understanding of the concept of object-oriented programming.

1.3 Executing a C++ Program


As is indicated in Savitch, the process to translate and execute a C++ program is more complicated than the brief
version given in the textbook. C++ programs typically go through six phases to be executed: edit, preprocess,
compile, link, load and execute.

A text editor is used to type the program and make corrections if necessary. The program is then stored in a file (the
.cpp file) on a secondary storage device such as the hard disk. This program is called the source code or source
program. The DevC++ integrated development environment (IDE) provides the text editor we use in this course, and
forms the interface to the compiler, the linker and the loader.

In the next step, the programmer gives the command to compile the program. The compiler checks for syntax errors
and translates the C++ source program into machine language code (also referred to as object code and stored in a
file with extension .o). In a C++ system, the compiler invokes a preprocessor program automatically before the
compiler’s translation phase begins. The C++ preprocessor executes special commands called preprocessor
directives. Preprocessor directives typically call for the inclusion of other text files in the file that has to be compiled
and therefore perform various text replacements. We use the MinGW compiler. Errors indicated by the compiler are
corrected using the text editor.

C++ programs usually contain references to functions defined elsewhere, such as in private (user-defined) libraries or
the standard libraries. The code for the functions residing in the libraries have to be combined with the object code
produced by the C++ compiler. This is done by a linker. A linker links the object code produced from your source
code with the code for the missing functions to create the executable code (saved in a file with the extension .exe).
Next, the executable code is loaded into the main memory for execution. This is done by the loader, which transfers
the executable program from disk to memory. Finally the computer executes the program.
90

1.4 Programming Methodologies


The two most popular programming paradigms are structured procedural programming and object-oriented
programming.

Structured Procedural Programming


Procedural programming focuses on the processes that data undergoes from input until meaningful output is
produced. During design the processing steps are described in an algorithm. These steps are typically sets of
operations executed in sequence after each other. Structured programming uses a technique called top-down design
or step-wise refinement. This refines or divides a problem into subproblems until eventually each subproblem is
straightforward enough to be solved easily. In the structured procedural approach each subproblem is normally
written as a separate function (or procedure) that is called by a main controlling function or module. A structured
procedural program defines variables and then calls a series of procedures to input values for the variables,
manipulate them and output the results.

Object-Oriented Programming
In object–oriented programming applications are organised around objects rather than processes. In the object-
oriented paradigm, a system is seen as a collection of interacting objects that models the interaction between objects
necessary to achieve the desired effect. In object-oriented programming, program components are envisioned as
objects that belong to classes and are similar to real-world objects; the programmer then manipulate the objects and
have them interrelate to achieve a desired result. With object-oriented analysis, design and programming, the focus
is on determining the objects you want to manipulate rather than the processes or logic required to manipulate the
data. Object-oriented programming involves three fundamental concepts: encapsulation, inheritance and
polymorphism.

Writing object-oriented programs involves creating classes, creating objects from those classes, and creating
applications, i.e. stand-alone executable programs, that use those objects. If they are designed properly, classes can
be reused over and over again to develop new programs.

An object generally represents a concrete entity in the real world such as a person, place or thing. Such an object has
certain characteristics or attributes and certain behaviours or actions. An object’s characteristics represent data or
facts that we know about the object. This is sometimes called the state of the object. The object’s behaviours are
actions that the object can take. These actions are expressed in functions or methods that execute algorithms. Each
object plays a specific role in the program design. The object interacts with other objects through messages or
function calls. Attributes and behaviours, i.e. an object’s data and algorithms, can be encapsulated, or combined
together to form a class.

A class is like a template or blueprint that can be used to construct or instantiate many similar objects. A class can
also be seen as a sort of user-defined data type, which we call an abstract data type (ADT). An object is an instance
of a particular class. A class hides information by restricting access to it. In effect the data and methods within an
object are hidden from users to prevent inadvertent changes. Users of the class simply need to understand how to use
the interface or interaction between the object and its methods.
91 COS1512/101/3/2011

Through inheritance it is possible to define subclasses that share some or all of the parent class’s attributes and
methods, but with more specific features. This enables reuse of code.

Polymorphism describes the feature in languages that allows us to interpret the same word differently in different
situations based on the context in which it is used. In object-oriented programs this means that similar objects can
respond to the same function call or message in different ways.
92

Chapter 4: Procedural Abstraction and Functions That Return a Value


Savitch: Section 4.6 Overloading Function Names

4.1 Overview
In this chapter both predefined (library) functions and programmer-defined functions are discussed. This includes
the use of value parameters, function invocation, procedural abstraction, and local and global scope. These concepts
are covered in COS1511, but in section 4.6, overloading function names, which is not covered in COS1511, is
explained.

4.2 Learning Objectives


After having worked through section 4.6, you should be able to:
• demonstrate that you understand the concept of overloading functions;
• write and use overloaded functions.

4.3 Notes
1. Study section 4.6.
2. Do the self-test exercises on page 268.
3. If necessary, work through the rest of the chapter to refresh your memory.

4.4 Different Notation and Conventions


Some of the notation and conventions used in Savitch may differ from those which were used in the COS1511 study
guide. Both versions are valid. For example:
• Function definitions may be given either before or after the main( ) function. However, if a function
definition is given after the main( ) function, the function prototype must be shown before the main( )
function.
• Savitch uses the term arguments for the parameters listed in parentheses after the function name in a function
call, while in COS1511 they were called actual parameters. See page 297 in Savitch for an explanation of the
different terms that have to do with parameters and arguments.
93 COS1512/101/3/2011

Chapter 5: Functions for All Subtasks


Savitch: Section 5.5 General Debugging Techniques

5.1 Overview
This chapter completes the description of C++ functions by discussing void functions and reference parameters.
All of these concepts are covered in COS1511. It also discusses testing and debugging functions. In this regard we
cover the assert macro in section 5.5.

5.2 Learning Objectives


After having worked through section 5.5, you should be able to:
• Use the assert macro to ensure that an expected condition is true at the location of the macro.

5.3 Notes
1. Study section 5.5.
2. Do the self-test exercises on page 322.
3. If necessary, work through the rest of the chapter to refresh your memory.
4. Work through the notes on using the Debugger with the prescribed C++ software available in Appendix A to
this tutorial letter as well as on the CD containing the prescribed C++ software.
94

Chapter 6: I/O Streams as an Introduction to Objects and Classes


Savitch: Sections 6.1 to 6.3

6.1 Overview
This chapter explains how to accept input from a file and send output to a file by means of streams. In the process of
explaining streams, the basic ideas of what objects are and how to use them in a program, is introduced.

The iostream header file is vitally important because it provides a consistent interface to all input/output in C++:
screen, keyboard and file. Furthermore, all input/output devices can be accessed in C++ through streams (using
operator overloading.) This input/output header file also provides access to a set of input/output routines that can be
used to output all the primitive (i.e. built-in) C++ types, and can be overloaded by the user to output any user defined
type. (Operator overloading is covered in Chapter 11.)

6.2 Learning Objectives


After having worked through sections 6.1 to 6.3, you should be able to:
• write programs that takes input from files (reading from files);
• write programs that send output to files (writing to files);
• format output with stream functions;
• manage character I/O correctly using the get and put member functions;
• use streams as arguments to functions;
• demonstrate that you understand the concepts of a class, an object, a member function among stream classes;
• declare an object of a class;
• use the dot operator to call a member function of an object.

6.3 Notes
1. Study sections 6.1 to 6.3.
2. Do the self-test exercises on pages 349, 360, 367, 377, 381 and 387.

6.4 File input and output


For programs that read their input from a file instead of the keyboard, we need to create the input file to hold our data
before running the program. Any text editor (not a word processor like MS Word, WordPad or WordPerfect!)
may be used. For example, we may use Notepad or the DevC++ editor to create the input file for Display 6.1 on
page 341 in Savitch as follows:
1. Open the editor.
2. Type in the input data in the order that the program will read it.
3. Save the file, giving it a meaningful name, e.g. infile.dat.

In Display 6.1 the input-file stream variable in_stream is declared with the statement
ifstream in_stream;
The statement:
in_stream.open("infile.dat");
95 COS1512/101/3/2011

connects the file infile.dat (created as described above) to the input-file stream variable by means of the open
member function. If the input file and the program file have not been saved in the same directory, the full path name
for the input file should be supplied. In this example infile.dat is the external file name, and in_stream the stream
name used as the name of the file in the program.

Similarly, in Display 6.1 the output is written to the file outfile.dat. Output files are created by the program. The
output file outfile.dat will therefore be created by the program. We can read the content of the file using a text
editor, such as the DevC++ editor.

6.5 Classes and Objects


A class is a data type whose variables are objects, and an object is a variable that has member functions as well as the
ability to hold data values in its member variables. Objects are the basic units of programming in object-oriented
programming languages like C++. The attributes of an object are described through the values stored in its member
variables, while the member functions are used to execute the operations that can be performed on the object (its
behaviour).

6.6 File Names as Input


Giving a file name as input is discussed on pages 350 to 353 in Savitch. Note that the declaration for a variable to
hold the file name
char file_name[16];
on page 352 declares a C-string variable, and not a variable of the standard string class. In COS111U the standard
string class was covered, and both types of string variables are covered in chapter 8 in Savitch.

One can also use a variable of the standard string class to hold the name of a file given as input, as shown below.
Note that in this case when the name of the file is supplied as argument to the member function open, the string
variable must first be converted to a C-string with the c_str()member function of the string class. The
string member function c_str() converts a standard string to a character array.
string file_name;
ifstream in_stream;
cout << "Enter the name of the file to be processed: ";
cin >> file_name;
in_stream.open(file_name.c_str())

6.6 Header files


For keyboard/screen input/output you need to use #include <iostream>. Similarly, for file input/output you
need to use #include <fstream>. The fstream class inherits from the iostream class, so most header files
are arranged so that to #include<fstream> is sufficient to get the iostream header file included as well.
Note, however, that this may not be the case for all compilers.

6.7 Processing data files versus processing text files

Files from which data should be read as strings, ints, floats or a mixture of data types, e.g. ints and chars,
are called data files. Files which should be read and processed character by character, are called text files. The way in
96

which we read data files differ from the way in which we read text files.

The typical way to read a data file, i.e. a file containing values that should be processed as int, string or
float, is demonstrated below. Assume we have to process a data file called infile containing one int
followed by a string on each line:

ifstream infile;
infile1.open("InputFile.dat");
if (!infile)
{
cout << "Cannot open file "
<< "InputFile.dat" << " Aborting!" << endl;
exit(1);
}

int value;
string name;
while (infile>> value >> name) //this checks for the eof marker of infile
//before reading the data from the file
{
//process value and name
}
infile.close();

Processing the input file as a text file, i.e. a file consisting of characters which should be processed one by one, is
demonstrated below:

ifstream infile;
infile1.open("InputFile.dat");
if (!infile)
{
cout << "Cannot open file "
<< "InputFile.dat" << " Aborting!" << endl;
exit(1);
}

char ch;
infile.get(ch);
while (!infile.eof()) //explicit testing for eof of infile
{
//process ch
infile.get(ch);
}
infile.close();
97 COS1512/101/3/2011

Chapter 8: Strings and Vectors


Savitch: Sections 8.1 and 8.3

8.1 Overview
This chapter covers two topics that use arrays or are related to arrays: strings and vectors. Section 8.1 introduces C-
string variables, which are inherited from C. C-strings represent a string as an array with base type char. Arrays
have been covered in COS1511. Chapter 7 also covers arrays, and you may refer back to it if you need to refresh
your memory. Section 8.2 discusses the standard string class, which was dealt with in COS1511. You will not be
examined on section 8.2, but do refer to it if necessary. Section 8.3 introduces the container class vector in the
Standard Template Library. We do not cover the use of iterators to access vector elements sequentially, though this
is covered in Chapter 18 of Savitch.

8.2 Learning Objectives


After having worked through sections 8.1 and 8.3, as well as the subsection “Converting between string objects
and C-strings” on page 511, you should be able to:
• define and use C strings;
• define and manipulate a vector using the random access methods.

8.3 Notes
1. Study sections 8.1 and 8.3.
2. Do the self-test exercises on pages 483, 489 and 518.

8.4 Converting between string objects and C strings


This section explains how to convert a string object to a C string by using the string member function c_str(). In
section 6.6 on page 11 of this Study Guide, we use the c_str() function to convert an external file name in
string format to a C string, which is the format required by the stream member function open().

8.5 The class vector


The class vector is defined in the Standard Template Library (STL) for C++. The STL vector container is a
generalization of array. A vector is a container that is able to grow (and shrink) during program execution. A
container is an object that can contain other objects. The STL vector container is implemented using a template
class (templates are covered in Chapter 17).

A vector named v that can contain int values is declared with


vector<int> v;
In order to use it, we need to include the correct header file that contains the declarations of the vector class and to
make the names from the standard namespace available with:
#include <vector>
using namespace std;

A vector is a fixed-length group of elements of uniform type, indexed by integer keys. As mentioned before, vectors
can be considered to be a generalization of the built in C++ array type. However, they have several other notable
98

features not associated with the basic array. The main advantages of using vectors is that the size of a vector need
not be fixed and can be changed during program execution, which is not possible with an array. Vectors are also
important when the ability to rapidly access arbitrary elements is necessary, because, as with an array, individual
elements in a vector can be directly indexed. The elements in a vector are assumed to be unsequenced, but the
operation sort in the STL can be used to place the elements of a vector in order.

8.6 The Standard Template Library (STL)

The Standard Template Library (STL) standardises commonly used components through a set of containers (lists,
vectors, sets, maps, etc.) that hold objects, built-in objects and class objects. The containers keep the objects secure
and define a standard interface through which they can be manipulated. The STL also contains standard algorithms
that can be applied to the objects while they are in the container, for instance, to sort them, compare them, merge
objects into another container, find a specific object and many more operations. The STL algorithms use iterators,
which are similar to pointers, to operate on the objects in the containers. The algorithms manipulate the objects in a
standard way and the iterators ensure that the algorithms handle all and only the elements in the containers, and no
more. You do not need to be able to use the iterator access methods for vectors, though more information on using
iterators can be found in Chapter 18.
99 COS1512/101/3/2011

Chapter 9: Pointers and Dynamic Arrays


Savitch: Sections 9.1 and 9.2

9.1 Overview
This chapter introduces the concept of pointers and dynamic arrays.

9.2 Learning Objectives


After having worked through sections 9.1 and 9.2 you should be able to:
• define and manipulate basic pointer variables and dynamic variables;
• demonstrate that you understand the difference between automatic (ordinary) variables and dynamic variables;
• demonstrate that you understand the difference between static arrays and dynamic arrays.

9.3 Notes
1. Study sections 9.1 and 9.2 up to page 549.
2. Do the self-test exercises on pages 538 and 548.
3. We do not cover the subsections on Pointer Arithmetic and Multidimensional Dynamic Arrays.
100

Chapter 10: Defining Classes


Savitch: Sections 10.1 to 10.4

10.1 Overview
This chapter teaches you how to define your own classes. A class is a data type whose variables are objects. You
have already used some pre-defined data types such as int, char, string and ifstream. The chapter first
introduces structures as a first step toward defining classes. A structure (struct) can be viewed as kind of a
simplified class without member functions.

10.2 Learning Objectives


After having worked through sections 10.1 to 10.4 you should be able to:
• define and use your own structures (structs);
• define and use your own classes;
• understand all the terminology applicable to ADTs;
• create your own ADTs;
• write programs that use ADTs;
• demonstrate that you understand the concept of inheritance.

10.3 Notes
1. The terms structure and struct are often used as synonyms. The COS1511 study guide uses the term struct,
while Savitch uses structure to refer to the same concept.
2. Savitch uses the term class definition for the declaration of a class. This is also known as an interface for the
class or the class specification. Remember that a class is a data type, and the class definition specifies what
attributes the data type have, i.e. which values it can hold, as well as its behaviour, i.e. what it can do. When
we declare variables of a specific class, we say we instantiate objects of the class.
3. Study sections 10.1 to 10.4.
4. Do the self-test exercises on pages 569, 577, 586, 593, 604, 614 and 623.

10.4 Accessor functions


An accessor function is a member function that returns the value of a data member of the class. To ensure that
accessor functions do not change data members by mistake, we mark them with the keyword const.

A const member function promises not to change any class data that it uses. A use of const in a class object
declaration promises that the function won’t call any other function with the potential to change that object’s data
members. The compiler tries to enforce these promises.

Use of the const keyword requires consistency. As shown in the BankAccount example below, if you declare a
member function const in a class definition, you must use the const keyword in your definition of that member
function. If you use a const object for an argument, and do not declare the function with a const parameter, you
should get an error or a warning from your compiler.

To implement this in the class definition for the BankAccount class on page 588:
101 COS1512/101/3/2011

(a) Change the function prototypes for the accessor functions get_balance( ) in line 17 and
get_rate( ) in line 19 to:
double get_balance( ) const;
double get_rate( ) const;

(b) Change the headings of the member function definitions for get_balance( ) in line 85 and get_rate( )
in line 90 to:
double BankAccount::get_balance( ) const
double BankAccount::get_rate( ) const

In this way the compiler will give an error message if any statement in the body of either get_balance( ) or
get_rate( )attempts to change a data member. Pages 658 to 661 in chapter 11 further explains this concept.
102

Chapter 11: Friends, Overloaded Operators, and Arrays in Classes


Savitch: Sections 11.1 to 11.4
Savitch: Appendix 7 The this pointer
Savitch: Appendix 8 Overloading Operators as Member Operators

11.1 Overview
This chapter continues teaching you how to define your own classes. It introduces friend functions, and teaches you
how to overload common operators such as +, -, * and / so that they can be used in the same manner as with
predefined types such as int and double. It also explains how to use classes of arrays, and arrays as data members
of a class. Section 11.4 covers classes and dynamic arrays. This includes how to write destructors, copy constructors
and how to overload the assignment operator.

11.2 Learning Objectives


After having worked through sections 11.1 to 11.4 you should be able to:
• define and use friend functions;
• define and use functions to overload both binary and unary operators;
• declare and manipulate arrays of classes as well as classes that contains arrays as data members;
• write destructors;
• write and use copy constructors;
• overload the assignment operator.

11.3 Notes
1. Study sections 11.1 to 11.4, Appendix 7 on page 1044 and Appendix 8 on page 1047.
2. Do the self-test exercises on pages 643, 656, 662, 667, 669, 679, 685, 689, 701 and 705.
3. Note the use of the const modifier as explained on page 658. We use this trick to prevent accessor functions
from modifying data members.
4. Class definitions typically include a destructor.

11.4 Overloading operators as member functions


Appendix 8 explains how to overload operators as member functions. In the last paragraph on page 1047, Savitch
explains “When + is overloaded as a member operator, then in the expression cost + tax, the variable cost is
the calling object and tax is the argument to +.” This means that the compiler translates the expression cost +
tax into the expression cost.operator+(tax). This clearly shows that the function operator+ has only one
parameter, as is shown on page 1048 in Savitch.

The general form of functions to overload the binary operators as member functions of a class follows:
Function prototype (to be included in the definition of the class):
returnType operator#(const className&) const;
where # stands for the binary operator, arithmetic (e.g. +, -, *, /) or relational (e.g. ==, !=, >, >=, <, <=, &&, ||) to be
overloaded; returnType is the type of value returned by the function; and className is the name of the class
for which the operator is being overloaded.
Function definition:
103 COS1512/101/3/2011

returnType className::operator#(const className& otherObject) const


{
//Algorithm to perform the overloading operation
return value;
}

Compare this with the general syntax to overload binary operators as non-member (friend) functions:

Function prototype (to be included in the definition of the class):


friend returnType operator#(const className&, const className&) const;
where # stands for the binary operator, arithmetic or relational, to be overloaded; returnType is the type of value
returned by the function; and className is the name of the class for which the operator is being overloaded.

Function definition:
returnType operator#(const className& firstObject,
const className& secondObject) const
{
//Algorithm to perform the overloading operation
return value;
}

11.5 The this pointer and overloading unary operators.


Appendix 7 covers the this pointer. As an additional example we show how the this pointer can be used in
overloading the unary operators ++ and – in prefix position as member functions. (Note that overloading ++ and – in
postfix position differs from what we show here!)

The process of overloading a unary operator is similar to that of overloading binary operators. The only difference is
that in the case of binary operators, the operator has two operands. In the case of unary operators, the operator has
only one operand. So, to overload a unary operator for a class, note the following:
1. If the operator function is a member of the class, it has no parameters.
2. If the operator function is a non-member of the class (i.e. a friend function), it has one parameter.

We use the class Money from chapter 11, and overload the pre-increment operator ++. We first show how to
overload the pre-increment operator ++ as a friend function and then as a member function.

The general syntax to overload pre-increment operator ++ as a non-member function in prefix position can be
described as follows:

Function prototype (to be included in the definition of the class):


friend className operator++(className& incObject);
104

Function definition:
className operator++(className& incObject)
{
//increment object by 1
return incObject;
}

Following this general syntax, we can overload the increment operator++ in prefix position as a non-member
function as follows:
Function prototype (to be included in the definition of the class):
friend Money operator++(Money & M);

Function definition:
Money operator++(Money & M)
{

++M.all_cents;
return M;
}

The general syntax to overload the pre-increment operator ++ as a member function in prefix position can be
described as follows:

Function prototype (to be included in the definition of the class):


className operator++();

Function definition:
className className:: operator++()
{
//increment object by 1
return *this;
}

Following this general syntax, we can overload the increment operator++ in prefix position as a member function as
follows:
Function prototype (to be included in the definition of the class):
Money operator++();

Function definition:
Money Money::operator++()
{ ++all_cents;
return*this;
}
105 COS1512/101/3/2011

11.6 The Big Three: Destructor, Copy Constructor and operator =


In C++, three special functions are provided automatically for every class: destructor, copy constructor and
operator =. In many cases the default behaviour provided by the compiler can be accepted. Sometimes, however,
this cannot be done. This is typically the situation for classes with pointer data members. For these classes, three
things are normally done:
1. Include the destructor in the class.
2. Overload the assignment operator (operator = ) for the class.
3. Include the copy constructor.

Initially, we will show the destructor, assignment operator and copy constructor for a simple class, IntCell that
simulates a memory cell containing an integer value. The class declaration and implementation for class IntCell
is shown below. (Note that we use separate compilation in this example. If you have not studied separate
compilation yet, just ignore all the pre-processor directives starting with #.)

Specification (IntCell.h):
#ifndef INTCELL_H
#define INTCELL_H

class IntCell
{
public:
IntCell (int Value = 0); //constructor
int get_Value( ) const; //accessor
void set_Value(int x); //mutator

private:
int Value;
};

#endif

Implementation (IntCell.cpp):
#include "IntCell.h"

IntCell::IntCell(int InitialValue): Value (InitialValue)


{
}

int IntCell::get_Value( )const


{
return Value;
}

void IntCell::set_Value(int x)
106

{
Value = x;
}

11.6.1 Destructor
A destructor is a member function that is called automatically when an object of the class goes out of scope at the
end of a function, or is deleted explicitly by a delete statement. Destructors can do any “housekeeping” necessary,
such as to delete all dynamic variables created by the object. Just as the compiler creates a default constructor
automatically if no constructor has been specified for the class, the compiler creates a destructor automatically if one
is not included in the class definition. A class has only one destructor with no arguments. The name of the destructor
is distinguished from the no-parameter constructor by the tilde symbol ~.

To include a destructor for the class IntCell, we add ~IntCell as a member function to the class definition
(specification). The implementation for the destructor function ~IntCell, is as follows:
~IntCell ( )
{ //nothing to be done since IntCell contains only an int data member.
//If IntCell contained any class objects as member variables their
//destructors would be called
};

11.6.2 Copy Constructor


The copy constructor is a special constructor that is required to construct a new object, initialised to a copy of the
same type of object. A copy constructor therefore has one (usually const) call by reference parameter that is of the
same type as the class.

For any object, such as IntCell, a copy constructor is called


• When an object is declared and initialised by using the value of another object, such as
IntCell B = C;
IntCell B(C);
but not
B = C; //Assignment operator

• When, as a parameter, an object is passed using call by value (instead of by & or const &)
• When the return value of a function is an object

In the first case the constructed objects are explicitly requested. In the second and third cases temporary objects are
constructed. Even so, a construction is a construction and in both cases we are copying an object into a newly
created object.

By default the copy constructor is implemented by applying copy constructors to each data member in turn. For data
members that are primitive types (e.g. int, double or pointers), simple assignment is done. This is also the case
for the data member Value in class IntCell. For data members that are themselves class objects, the copy
constructor for each data member’s class is applied to that data member.
107 COS1512/101/3/2011

The prototype for the default copy constructor for IntCell is


IntCell(const IntCell & rhs); //copy constructor

with the following implementation:


IntCell::IntCell(const IntCell & rhs)
{
Value = rhs.Value;
}

11.6.3 The operator =


The copy assignment operator, operator =, is used to copy objects. It is called when = is applied to two objects
after both have been previously constructed. The expression lhs = rhs is intended to copy the state (i.e. the
values of the data members) of rhs into lhs. By default the operator = is implemented by applying operator
= to each data member in turn.

The prototype for the default assignment operator for IntCell is


const IntCell & operator=(const IntCell & rhs);

with the following implementation:


const IntCell & operator=(const IntCell & rhs)
{
if (this != &rhs) //standard alias test to avoid self-assignment
Value = rhs.Value;
return *this;
}
As mentioned on page 705 in Savitch, to make sure that the object is not copied to itself, an alias test is done with
if (this != &rhs) //standard alias test to avoid self-assignment

An additional keyword in C++, the pointer this points at the current object. We can think of the pointer this as a
homing device that, at any instant in time, tells us where we are. (Also see Appendix 7 on page 1044 in Savitch for
more on this). The pointer this thus refers to the address of the current object, while the unary address operator
& in combination with rhs, as in &rhs, refers to the address in memory where rhs is stored. If these two addresses
are the same, i.e (this == &rhs), the same object appears on both sides of the assignment operator and the
operation should not be executed.

If the object is not copying to itself, the operator= is applied to each data member. IntCell has only one data
member Value, so only one statement is needed:
Value = rhs.Value;

*this is the current object, and returning *this will return a reference to the current object. This allows
assignments to be chained, as in a = b = c.
108

11.6.4 Problems with the defaults


If a class consists of data members that are exclusively primitive types (such as int, double, vector<int>,
string, etc.) or objects for which the defaults make sense, the defaults can be accepted. However, when a class
contains a data member that is a pointer, the defaults are no longer sufficient.

Suppose that the class contains a single data member that is a pointer. This pointer points at a dynamically allocated
object. If we adapt the specification for class IntCell so that its single member is a pointer to an integer, the
specification and implementation changes to what is shown below. Note that the default destructor, copy constructor
and assignment operator will be used since we do not define our own:

Specification (IntCell.h):
#ifndef INTCELL_H
#define INTCELL_H

class IntCell
{
public:
IntCell (int Value = 0); //constructor
int get_Value( ) const; //accessor
void set_Value(int x); //mutator

private:
int *Value;
};

#endif

Implementation (IntCell.cpp):
#include "IntCell.h"

IntCell::IntCell(int InitialValue)
{
Value = new int(InitialValue);
}
int IntCell::get_Value( )const
{
return *Value;
}

void IntCell::set_Value(int x)
{
*Value = x;
}

The output from the application below in which class IntCell is used, exposes problems with accepting the default
109 COS1512/101/3/2011

destructor, copy constructor and assignment operator:

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

int main() {
IntCell a(2);
IntCell b = a;
IntCell c;

c = b;
a.set_Value(4);
cout << a.get_Value() << endl << b.get_Value() << endl << c.get_Value()
<< endl;
return 0;
}

Output:
4
4
4
Press any key to continue . . .

The output produces three 4s, even though logically only a should be 4. The problem is that the default copy
constructor and the default operator= both copy not the objects being pointed at, but simply the value of the
pointer Value. Thus a.Value, b.Value and c.Value all point at the same int value. This is called shallow
copying: i.e. the pointer rather than the contents of the address to which the pointer is pointing, is copied. Typically,
we would expect a deep copy, in which a clone of the entire object is made.

A second less obvious problem is a memory leak: the int initially allocated by a’s constructor remains allocated
and needs to be reclaimed. The int allocated by c’s constructor is no longer referenced by any pointer variable. It
also needs to be reclaimed, but we no longer have a pointer to it. This is because the default destructor does nothing.
We have to call delete ourselves. To fix these problems, we implement the Big Three, as shown below:

Specification (IntCell.h):
#ifndef INTCELL_H
#define INTCELL_H

class IntCell
{
public:
IntCell (int Value = 0); //constructor
110

IntCell (const IntCell & rhs); //copy constructor


~IntCell( ); //destructor
const IntCell & operator=(const IntCell & rhs); //overloaded assignment

int get_Value( ) const; //accessor


void set_Value(int x); //mutator

private:
int *Value;
};

#endif

Implementation (IntCell.cpp):
#include "IntCell.h"

IntCell::IntCell(int InitialValue) //constructor


{
Value = new int(InitialValue);
}

IntCell::IntCell (const IntCell & rhs) //copy constructor


{
Value = new int (*rhs.Value);
}

IntCell::~IntCell( ) //destructor
{
delete Value;
}

const IntCell & IntCell::operator=(const IntCell & rhs) //overloaded


//assignment
{
if (this != &rhs) //standard alias test to avoid self-assignment
*Value = *rhs.Value;
return *this;
}

int IntCell::get_Value( )const //accessor


{
return *Value;
}

void IntCell::set_Value(int x) //mutator


111 COS1512/101/3/2011

{
*Value = x;
}

Running the same application as before, now gives the correct output, as shown below:

Output:
4
2
2
Press any key to continue . . .

To summarize, when a class has pointer members and a constructor allocates memory from the free store you need a
copy constructor to guarantee correct initialization of an object of that class type from another object of that class
type. And you also need a destructor to guarantee that free store memory pointed to by members are deallocated
when the class object goes out of scope. If you assign objects of such a class to one another, then you need to
overload the operator = to guarantee that the data pointed to by objects’ pointers is copied, and not just the pointers.

Note that defining operator = has no effect on the behavior of the class objects during copy construction.
Similarly, defining a copy constructor does nothing for the assignment operator. Operator = is invoked when
assignment is made to a class object. The destructor is called when an automatic object goes out of scope, and
when the destructor is called explicitly.
112

Chapter 12: Separate Compilation and Namespaces


Savitch: Sections 12.1 to 12.2 up to page 743

12.1 Overview
This chapter teaches you how to divide an ADT into separate specification and implementation files. It also
discusses how to implement separate compilation as well as conditional compilation using pre-processor directives.
This chapter also discusses namespaces. Creating your own namespaces is beyond the scope of this module, but you
do have to understand the concept of a namespace.

12.2 Learning Objectives


After having worked through sections 12.1 to 12.2 you should be able to:
• divide an ADT into separate specification and implementation files;
• understand the concept of a namespace.

12.3 Notes
1. Study sections 12.1 to 12.2 up to page 743.
2. Study the sections on Include Directives and Namespaces on pages 82 and 83, and Namespaces Revisited on
page 256 to 258. In this course we will only use the standard namespace std.
3. Do the self-test exercises on pages 740.

12.4 Separate Compilation


C++ allows you to divide a program into parts. Each part can be stored in a separate file and can be compiled
separately and then linked together when (or just before) the program is run. Any software project which is slightly
more than trivial is generally divided into separate files.

Programs that use user-defined classes usually also use multiple source files. Typically the definition (specification)
of the class will be placed in a .h file, called the interface or specification file, while the implementation will be
placed in a .cpp file. This offers, among others, benefits such as compiling the files separately and software reuse.
For example, the interface may be required (with #include) on multiple occasions within one or more projects’
code, but the implementation need only be compiled once.

To use separate compilation, you create a project to which the files to be included can be added. See appendix A in
Tutorial Letter 101 for instructions on how to do this in DevC++.

12.5 Preprocessing and conditional compilation


Preproccessing occurs before a program is compiled. Possible actions include:
• inclusion of other files in the file being compiled (by means of file inclusion directives),
• definition of symbolic constants and macros,
• conditional compilation of program code and
• conditional execution of preprocessor directives.
All preprocessor directives begin with #, and only whitespace characters may appear before a preprocessor directive
on a line. Preprocessor directives are not C++ statements, so they do not end in a semicolon (;).
113 COS1512/101/3/2011

To prevent multiple declarations of a class, we use the pre-processor directives #ifndef, #define and #endif
to control the inclusion of the header file so that the same definitions are not included repeatedly. This is called
‘conditional compilation’.

The #include preprocessor directive causes a copy of a specified file to be included in place of the directive. The
two forms of the file inclusion directive (#include <filename> and #include "filename") indicate
where (which directory) the preprocessor should find the file to be included.

To include a predefined header file use #include <filename>, e.g.


#include <iostream>
The < and > characters tells the compiler to look where the system stores predefined header files.

To include a header file you wrote, use #include "filename", e.g.


#include "dtime.h".
The " and " characters usually cause the compiler to look in the current directory for the header file. If the filename
is given in terms of an absolute file system pathname, then the file is taken from that absolute location. For example,
the following directive indicates that that the file sample.h can be found in the directory \example\source on
the C: drive.
#include "C:\example\source\sample.h"

Once the preprocessing has been done, the compiler translates the source code into object code, stored in a .o file.
The linker then links the object code with the code from libraries for functions that are included (with #include) to
create the executable code, stored in a .exe file.
114

Chapter 14: Recursion


Savitch: Sections 14.1 to 14.2 up to page 831

14.1 Overview
This chapter introduces recursion. Recursion is a difficult topic to grasp. However, it’s very easy to apply once you
understand it. Recursion means allowing a function or procedure to call itself. It keeps calling itself until some limit
is reached.

14.2 Learning Objectives


After having worked through sections 14.1 to 14.2 you should be able to:
• understand the concept of recursion;
• write recursive functions according to a recursive definition for a problem.

14.3 Notes
1. Study sections 14.1 and 14.2 up to page 831.
2. Do the self-test exercises on page 822, 826 and 830.

14.4 Recursion
The summation function, designated by an uppercase ∑ (Sigma) in mathematics, is a popular example of recursion:
n n-1

∑i = ∑i + n
i=1 i=1

or, put in a different way:

sum(n) = 1 if n = 1
= sum(n-1) + n if n > 1

Written as a recursive function, this gives:

int calc_sum (int num)


{
int sum;
if (num == 1) //base case
sum = 1;
else
sum = calc_sum(num-1) + num; //recursive call
return sum
};
Suppose you call calc_sum for 3:
int answer = calc_sum(3);
115 COS1512/101/3/2011

calc_sum (3) becomes calc_sum (2) + 3.


calc_sum (2) becomes calc_sum (1) + 2.
At 1, the recursion stops and becomes 1.
calc_sum (2) becomes 1 + 2 = 3.
calc_sum (3) becomes 3 + 3 = 6.
answer becomes 6.

Recursion works backward until a given point is reached at which an answer is defined (the base case), and then
works forward with that definition, solving the other definitions which rely upon that one.

All recursive procedures/functions should have some sort of test to stop the recursion. Under one condition, called
the base condition, the recursion should stop. Under all other conditions, the recursion should go deeper. In the
example above, the base condition is if (num == 1). If you don’t build in a base condition, the recursion will
either not take place at all, or become infinite.
116

Chapter 15: Inheritance


Savitch: Section 15.1 up to page 879

15.1 Overview
This chapter introduces the concept of inheritance, a key feature of object-oriented programming. Inheritance is the
ability to define new classes from existing classes. The new classes that we create from the existing classes are called
derived classes; the existing classes are called the base classes. The derived classes inherit the properties of the base
classes. So rather than create completely new classes from scratch, we take advantage of inheritance and reduce
software complexity. We only cover section 15.1: Inheritance Basics. Polymorphism is not covered in this module.

15.2 Learning Objectives


After having worked through section 15.1 you should be able to:
• distinguish between ‘is-a’ relationships and ‘has-a’ relationships;
• understand the role of public inheritance in class design;
• create new classes by inheriting from existing classes;
• understand how inheritance promotes software reusability;
• understand the notions of base classes and derived classes;
• understand the effect of the access-specifier labels (i.e private, public and protected) in terms of
public inheritance.
• define constructors for a derived class;
• redefine member functions;
• demonstrate that you understand the difference between redefining a member function in a derived class and
overloading a member function.

15.3 Notes
1. Study section 15.1 up to page 879.
2. You can safely ignore all references to namespaces other than std. In Display 15.1 on page 858, for example,
lines 9 and 28 can be omitted, and the same applies to the other displays in this chapter.
3. Do the self-test exercises on pages 872 and 879.

15.3 Inheritance
15.3.1 The Purpose of Inheritance
The primary purpose of inheritance is to reuse code by exploiting the ‘is-a’ relationship between objects. Software
reusability saves time in program development. It encourages the reuse of proven and debugged high-quality
software, thus reducing problems after a system becomes functional. Significant overlap between two classes
indicates a potential case for inheritance.
117 COS1512/101/3/2011

15.3.2 The ‘is-a’ relationship


In the real world, objects exist in relation to one another. In solving problems we need to be as close to the problem
as we can, within abstraction that allows us to ignore details in order to solve our problem. In our problem, we may
describe one object as being like another, even saying one object ‘is-a’ type of some other object.

In an example of ‘is-a’ relationships, we might think of a class of (general) vehicles, and then think of a kind of
vehicle for carrying passenger (automobiles), another kind that is small and carries cargo in the open (pickup truck),
still another that carries cargo in an enclosure (van), others yet that carry cargo enclosed and are articulated - tractor-
trailer). The Truck, Van, and Car classes inherit their common features from the class Vehicle.

In these cases, a car is a vehicle, so are pickups, vans, and tractor-trailers. A car ‘is a’ vehicle; a pickup truck ‘is a’
vehicle, and so on. The class abstraction of vehicle is the base class and the vehicles that bear the ‘is a’ relation to the
base class are derived classes. In this example, the base class contains the features common to all types of vehicles.
The derived class inherits all those common features and adds its own, extra, additional features to the base class to
form its distinctiveness. In this way, the common features (commonalities) are encapsulated in the base class, and the
distinctions are encapsulated in the derived class. The commonality is passed from the base class to the derived class
with inheritance. A derived class is therefore more specific than its base class. This relationship is known as the ‘is-
a’ relationship. The ‘is-a’ relationship specifies that one abstraction is a specialization of another. If we write this
example in
C++, we have
class Vehicle {/* . . . */};
class Car : public Vehicle { /* . . . */};
class Truck : public Vehicle { /* . . . */};
class TractorTrailer: public Truck {/* . . . */};
class StationWagon : public Car {/* . . . */ };

We see that inheritance creates a new class, called the derived class, that is an extension, specialization or
modification of one or more existing classes, called the base classes. In the situation where there is only one base
class, we have single inheritance. Where there is more than one base class, multiple inheritance occurs. In this,
example, we could illustrate multiple inheritance by defining
class Emergency {/* . . . */};
and have had a class PoliceCar inherit from both class Car and class Emergency. Or we could have a class
Ambulance inherit from both class Truck and class Emergency. The PoliceCar and Ambulance would
inherit features from Car and the derived class adds its distinguishing features. Since multiple inheritance is beyond
the scope of this module, we will not discuss it further.

Notice that the ‘is-a’ relationship is transitive (that is, a TractorTrailer is a Truck, a Truck is a Vehicle,
and therefore a TractorTrailer is a Vehicle), but it is not reflexive (that is, not all Vehicles are
TractorTrailers). Another way of expressing the ‘is-a’ relationship is to say that a TractorTrailer is a
kind of Truck and that an Truck is a kind of Vehicle. See also text box on page 867 in Savitch.

In addition to the ‘is-a’ relationship that represents inheritance, two other relationships between abstractions are
118

commonly used on object-oriented design, namely the ‘has-a’ and ‘uses-a’ relationships. The ‘has-a’ relationship
says that some object is part of another. The ‘has-a’ relationship implies containment. For example, a car has an
engine. The ‘uses-a’ relationship says that one object uses another object in some way. This usually realized by one
object communicating with another via member functions. For example, suppose the operating system has a clock
object that maintains the current date and time. The clock object has member functions that return the current date
and time. Other objects that need the date or time, use the clock object by calling the appropriate member functions
to fetch the current date or time.

15.4 Public Inheritance


Public inheritance should be used when a new class (the derived class) describes some set of objects that is a subset
of the objects being described by the base class. This relationship is known as the ‘is-a’ relationship.

So what does public inheritance mean? Consider the classes Base and Derived:

class Base
{
public:
int x;
protected:
int y;
private:
int z;
};

class Derived : public Base


{
public:
int total( ) const
{
int sum = x;
sum += y;
//sum += z; //cannot access z directly
sum += q;
return sum;
}
private:
int q;
};

Public members of the Base class are public members of the Derived class too. The Derived class inherits all
data members and all member functions from the Base class, but it can access only those that are not private. That
is, a derived class can access public and protected members of its base class. In the example, class Derived can
access x and y directly but not z, because z is private in class Base. If we want to access z which is a private data
member in the Base class, then we can access z in one of two ways:
(1) by creating a public / protected accessor in class Base, such as
int get_z( ) const
{
return z;
}

(2) or we could make z protected (more about this on page 870 in Savitch).
119 COS1512/101/3/2011

Now consider the following client program that instantiates objects of type Base and Derived:

int main( )
{
Base b;
Derived d;
cout << b.x;
cout << d.x;
//cout << b.y;
//cout << d.y;
//cout << b.z;
//cout << d.z;
}

Since x is public in class Base, it is also public in class Derived through public inheritance. Therefore we can
access x in the client program. But we cannot access y because it is a protected member of both Base and
Derived. And of course we cannot access z because it is private.

Note, that the access specifier for class inheritance defaults to private. If class Derived has base class
Base:
class Base {/* . . .*/};
class Derived : access-specifier Base
{ /* . . . */};
//where access-specifier is one of public, protected, private
then the access that is granted to member functions of class Derived depends on the access-specifier selected. If
the access-specifier is omitted, access to all members of the base class automatically defaults to private. This would
mean that Derived has no access to the member functions and data members of Base.
120

Chapter 17: Templates


Savitch: Sections 17.1 to 17.2

17.1 Overview
This chapter discusses C++ templates. C++ templates provide a way to reuse code by defining functions and classes
that have parameters for type names. Templates are very useful when implementing generic constructs like vectors,
stacks, lists and queues, which can be used with any arbitrary type.

17.2 Learning Objectives


After having worked through sections 17.1 to 17.2 you should be able to:
• implement function templates;
• implement class templates;
• compare and contrast function overloading with the use of templates.
17.3 Notes
1. Study sections 17.1 and 17.2.
2. Once again, you can safely ignore all references to namespaces other than std, such as in lines 12 and 49 of
Display 17.4.
3. The MinGW compiler does not allow separate compilation of templates. Therefore you need to include the
template definition (i.e. its declaration and the implementation thereof) in the same (header) file. Note that
you can place the template definition in a separate file and use a #include directive to include the template
definition when you need to use it.
4. Note that the use of the keyword class in a template prefix does not mean that you can write only a class
name there. You can use any type name already defined in the language such as, int, float, double, or
any identifier that is a user defined type (such as a class, structure or enum).
5. Do the self-test exercises on pages 949, 956 and 965.

© Unisa

2011

You might also like