ICS 45C Fall 2021
Exercise Set 8

Due date and time: Tuesday, November 30, 11:59pm

Getting started

First of all, be sure that you've read the Reinforcement Exercises page, which explains everything you'll need to know, generally, about how the reinforcement exercises will work this quarter. Make sure you read that page before you continue with this one.

Before you begin work on these reinforcement exercises, there's a chore that you'll need to complete on your ICS 45C VM to get it set up to proceed.

Refreshing your ICS 45C VM environment

Even if you previously downloaded your ICS 45C VM, you will probably need to refresh its environment before proceeding with these exercises. Log into your VM and issue the command ics45c version to see what version of the ICS 45C environment you currently have stored on your VM. Note, in particular, the timestamp; if you see a version with a timestamp older than the one listed below, you'll need to refresh your environment by running the command ics45c refresh to download the latest one before you proceed with these exercises.

2021-11-25 08:05:01
Exercise Set 8 template added

If you're unable to get outgoing network access to work on the ICS 45C VM — something that afflicts a handful of students each quarter — then the ics45c refresh command won't work, but an alternative approach is to download the latest environment from the link below, then to upload the file on to your ICS 45C VM using SCP. (See the Project #0 write-up for more details on using SCP.) Once the file is on your VM, you can run the command ics45c refresh_local NAME_OF_ENVIRONMENT_FILE, replacing NAME_OF_ENVIRONMENT_FILE with the name of the file you uploaded; note that you'd need to be in the same directory where the file is when you run the command.

Creating your project directory on your ICS 45C VM

A project template has been created specifically for this set of exercises, containing a similar structure to the basic template you saw in Project #0. Among other things, it contains a version of the gather script that's different from the ones in the projects, so you'll absolutely need to use the set8 template for these exercises, as opposed to the basic one.

Decide on a name for your project directory, then issue the command ics45c start YOUR_CHOSEN_PROJECT_NAME set8 to create your new project directory using the set8 template. (For example, if you wanted to call your project directory set8, you would issue the command ics45c start set8 set8.)

Problem 1 (2 points)

This week, we talked about a technique known by its acronym: RAII. In those notes, you'll find two versions of a function called downloadFile. The first one makes no attempt to handle exceptions, which means the inability to acquire the lock, connect to the network, or open the file can potentially lead to a similar failure to call close() and delete those objects subsequently, even in the case of failure. Let's focus our attention only on the second of these examples.

Now let's assume that we've made the following changes in the design of the code used by that second version of the downloadFile function.

First, rewrite the downloadFile function based on these new assumptions, but make sure that it is still true that a failure to acquire the lock, establish a network connection, or open the file will not lead to memory or resource leaks (i.e., any dynamically-alllocated memory will have been deleted, any resources such as locks, connections, or files will have been closed).

Next, explain in a short paragraph whether this new version of downloadFile is simpler than the second version from the notes that you've rewritten. If it was simpler, explain specifically why the RAII technique was instrumental in the improvement. If it wasn't simpler, explain specifically what's missing from the RAII technique that prevented your new function from being an improvement.

What to submit

Add one PDF file to your problems directory with this name: problem1.pdf, which contains both your newly-written downloadFile function, followed by your explanation of whether and wy RAII led to an improvement.

(Even though you're writing code here, you're writing something hypothetical enough — we don't actually have Lock, Connection, and File classes to test with — that there's no reason to write this in a .cpp file, since there will be no way to compile or run it.)

Problem 2 (4 points)

In the file problems/problem2.hpp, you will find the declaration of (the public portions of) a class template called TextLineReader. Additionally, in the file app/main.cpp, you will find an example of its usage, which you'll want to review after reading the rest of this problem, as it may answer some of the questions you have about it.

A TextLineReader is an object that can read a text file one line at a time, parsing each line and turning it into an object of some type. The reason we've implemented it as a class template is so that different TextLineReaders can transform their file into different types of objects; for example, a TextLineReader<int> will return an int from every line, while a TextLineReader<Student> will return a Student instead. Because TextLineReader itself can't know how to transform each line from the file into the corresponding result type, a line parser function is provided, which does that transformation (i.e., takes each line's text and returns the appropriate kind of object, or throws an exception if that transformation fails because the format of the line is incorrect).

Write the implementation of the TextLineReader class template. You may not change any of the public declarations that were provided, but you can add anything you'd like — including public or private member functions, private member variables, and so on — but you'll need to meet all of the following design requirements.

Things to be aware of

Note that you'll find that the code will not compile and link properly until after you've finished your implementation, so if you immediately try to build it, that is expected to fail; you're not done yet.

We haven't discussed text files, but reading from them and writing to them is actually pretty straightforward, given that we've already used std::cin and std::cout. A std::ifstream is an input stream that reads from a file (that's what the if stands for), while a std::ofstream is an output stream that writes to a file. While most of what we need is pretty much the same as it is when using std::cin or std::cout, there are a couple of concepts that are added to the mix: Files need to be opened (and this can fail) and input files eventually reach an "end" (i.e., if a file has 100 lines in it, we can't continue reading from it once we've read all 100 of them). Lots of information about these parts of the C++ Standard Library can be found at cppreference.com, among other places.

What to submit

Modify the problem2.hpp in your problems directory with your complete implementation of the TextLineReader class template.

Problem 3 (2 points)

We've discussed why it's so often the case that we write C++ templates in header files rather than source files, but let's be sure we have our minds wrapped around it; it's a critical part of being able to use templates in our designs.

Suppose you've decided to write a function template that you expect to use in many different source files. Suppose, further, that you haven't followed the basic advice of writing C++ templates in header files, but have instead done the following:

Now suppose that you've written a separate source file, y.cpp, in which you've written #include "x.hpp" near the top and then instantiated the function template by calling it, and that your call to the function template is a legal instantiation (i.e., it has the right number of parameters and they're compatible with any constraints introduced within the template).

Will it always be the case that this program can be built?

What to submit

Add one PDF file to your problems directory with this name: problem3.pdf, which contains your answers to this question.

Problem 4 (2 points)

During our conversation about Templates, we talked about how template parameters have constraints associated with them, which is to say that we're not always allowed to instantiate them with any template parameters we want; the parameters have to be reasonable, relative to what the template requires.

Now consider the Point class template from the Templates notes. Let's explore what constraints are associated with each of its member functions. For each of the member functions listed below, what are the constraints on any template parameters associated with it? List the constraints separately (e.g., with a bulleted list); be as specific as possible about which constraints to include, but no single constraint requires you to write more than a few words.

  1. The constructor that takes three CoordinateType arguments.
  2. The copy constructor that initializes a Point of one type from a Point of a potentially different type.
  3. The assignment operator that assigns a Point of one type from a Point of a potentially different type.
  4. The x, y, and z member functions. (Note: Both overloads of all three of these will have the same constraints. Do you see why?)
  5. The distanceFrom member function.

What to submit

Add one PDF file to your problems directory with this name: problem4.pdf, which contains your answers to this question.


In Canvas, you'll find a separate submission area for each problem. Submit your solution to each problem into the appropriate submission area. Be sure that you're submitting the correct file into the correct area (i.e., submitting your Problem 1 solution to the area for Problem 1, and so on). Under no circumstances will we offer credit for files submited in the incorrect area.

Submit each file as-is, without putting it into a .tar.gz file or arranging it in any other way. (There is a gather script in the set8 template, but there's no need to use it.) If we asked for a PDF, for example, all we want is a PDF; no more, no less. If you submit something other than what we asked for, we will not be offering you any credit on the submission. There are no exceptions to this rule.

Of course, you should also be aware that you're responsible for submitting precisely the version of your work that you want graded. We won't regrade an exercise simply because you submitted the wrong version accidentally, and we won't be able to offer any credit on exercises that you forgot to submit.

Can I submit after the deadline?

Unlike some of the projects in this course, the reinforcement exercises cannot be submitted after the deadline; there is no late policy for these. Each is worth only 3% of your grade, so it's not a disaster if you miss one of them along the way.

Can I work on this outside of the VM?

Yes, but be aware that you must submit the files in the appropriate format, and that any C++ code you submit must compile and run on the ICS 45C VM.