Container classes can be made much more useful if they are converted to template classes. Conversions are often straightforward, but clients must be aware of the requirements the template implementation places on the objects stored in the container. Often such objects must support copy constructors, assignment operators, and possibly other overloaded operators.
Adding additional functionality to an existing ADT is possible by editing the header file and ensuring that the definitions of the new functions are compiled and linked with the driver (or main) file.
Task 1. Open the project file and examine the file driver.cpp. Run the program to convince yourself that there are no problems with the project. Examine the file list.h to observe the class declarations for lists used in this lab. Note that there are no associated cpp files; all of the definitions are included in the header file. This is a BAD practice (in general) as it means the List class must be recompiled every time the application is recompiled - even if there have been no changes to the List class. It was done this way in this lab because you are going to be converting this class to a template class; template classes are defined in a single header file.
Note that the List class does not contain a copy constructor (it is commented out). This means that a
_____________ copy constructor is provided by the system. This system provided copy constructor copies the raw bytes of one object into another; no notice is taken of the data types of the object's members. Let's look at the consequences of this.
Task 2: Change the TASK variable to task 2. Read through the TASK 2 code to see how the copy constructor is used. The application creates a list, puts some numbers into it, displays it and displays the addresses of the list nodes. Next, a copy of the list is created using the copy constructor supplied by the system. This copies only the data members of the List object. What are the names of these data members?
_________________ and __________________
The second list is then displayed, along with the addresses of the nodes.
While executing the program in this task, do not press Enter until the instructions in the lab say to do so. Build and run the project. What do you notice about the addresses of the nodes of the first list and the nodes of the second list?
________________________________________________________________
In general, this is not a good idea for two distinct lists. Press Enter now;
as execution leaves the block in which the second list is declared, its
destructor will be called. Note the addresses of the nodes that are deleted from
the heap. Press Enter again and tell
the error message that is displayed.
What node was being destroyed when the error occurred? (____________, _____________).
One part of this is garbage, the other part is not (compare to the list
of nodes already destroyed). Use this information to explain why the destruction
of this node caused the program to crash.
You should edit the file list.h so that it now contains an additional constructor declaration for a copy constructor (by removing the comment // before the prototype). The parameter is a reference to a constant List which contains items of type int. Next, uncomment the copy constructor definition in list.h and complete it. This constructor will be invoked whenever a new List object is created from an existing List. The constructor should make a copy of the first List in such a way that each list has a separate collection of list nodes.
Now run the project. If your constructor works correctly, the nodes of the two lists should have different addresses. If not, try again or get help from a TA! The destruction of the two lists should proceed without error.
Task 3. This List class is great, but it only works for Lists of integers. Change the TASK variable to 3 and build the project. Write the first error message and the line it refers to.
Error: _______________________________________________________________
Line: _______________________________________________________________
Explain why this statement causes an error:
In the function, testFloatList, change the datatype in the declaration of the List to List<float>. This will require a template class called List. All of the changes to convert the classes List.h and Listnd.h into template classes are found in those files. Make the changes. You should be able to get a clean compile and successfully run the test.
This conversion is relatively straightforward, however we must impose certain requirements on the datatypes we use to instantiate the List template. If we decide to create a list of objects of type XXX (i.e. List<XXX>), we must require that the type XXX objects support a copy constructor. Find the line in Listnd.h that requires a copy constructor for an object of type someType.
____________________________________________________________
Of course, int's and float's have copy constructors, as do all the primitive types. The requirement becomes non-trivial when we create a List of user defined objects such as List<Fract>. We must also be careful if we create Lists of things that are referred to by address. A List<char *> for example might create some real problems with memory allocation. In general, when you create templates, be sure to document what properties of the parameter type are used in your implementation. Consider things like assignment operators, default and copy constructors, relational and equality operators, and so on.
Task 4: This is EXTRA CREDIT. Check here if you have completed this task: __________
Change the TASK variable to 4. We are going to add a new operation to the List data type: concatenation of Lists to allow this statement: ListA += ListB;. You must implement it as a non-member, non-friend function. Place the operator+= declaration and implementation in List.h. This function must append the elements of the second list to the first list. The original second list must not be changed (be sure to reflect this in the function header). The operator does not need to return anything (use void).
Turn in this sheet stapled to the printouts of the files List.h and Listnd.h after you have completed the lab. As usual, you should leave the computing environment no worse (and hopefully better) than you found it.