Description
Introduction:
The objective lab is to understand the low-level design concepts of multiple inheritance, container classes and Iterator classes.
Exercise A – Multiple-Inheritance (10 marks)
This exercise is the continuation of exercise B in Lab 2. You have already completed exercise B in lab 2 and in this lab, you will add more code to your existing files in lab 2. C++ allows a class to have more than one parent: This is called multiple inheritance. For example, if we have two classes called B and C, and class D is derived from both classes (B and C), we say class D has two parents (multiple inheritance).
This is a powerful feature of C++ language that other languages such as Java do not support. For the details, please refer to your class notes. What to Do In this exercise, you should add two new classes to your program completed in lab 2, exercise B: Class Circle: This class is supposed to be derived from class Shape, and should have a data member radius.
In addition to its constructor, it should support the similar functions as class Rectangle, such as area, perimeter, get, set, and display. You should create two files for this class: called circle.h and circle.cpp Class CurveCut: CurveCut represents a shape that needs properties of class Rectangle and class Circle.
In fact, it’s a rectangle that its left top corner can have an arch-form cut (see the following picture). This class must be derived from class Rectangle and class Circle. Where the origins (x and y coordinates) of both shapes are the same.
This class, in addition to a constructor, should support the following functions: – area – that calculates the highlighted area of the above figure. – perimeter – that calculates and returns the perimeter of highlighted areas. – display – that displays the name, x, y coordinates of the origin of the shape, width, and length (as shown in the picture above), and radius of the cut, in the following format: CurveCut Name: X-coordinate: Y-coordinate: Width: Length: Radius of the cut.
Note: The radius of the circle must be always less than or equal to the smaller width and length. Otherwise, the program should display an error message and terminate. You should also add some code to function run in class GraphicsWorld to: – test the member functions of class CurveCut. – use an array of pointers to Shape objects, where each pointer points to a different object in the shapes hierarchy. Then test the functions of each class again.
A sample code segment that you can use to test your program is given in the following box (you can add more codes to this function if you want to show additional features of your program). void GraphicsWorld::run(){ /****************************ASSUME CODE SEGMENT FOR EXERCISE A IS HERE ************************/ #if 0 cout << “\nTesting Functions in class Circle:” <<endl; Circle c (3, 5, 9, “CIRCLE C”); c.display(); cout << “the area of ” << c.getName() <<” is: “<< c.area() << endl; cout << “the perimeter of ” << c.getName() << ” is: “<< c.perimeter() << endl; d = a.distance(c); cout << “\nThe distance between rectangle a and circle c is: ” <<d; CurveCut rc (6, 5, 10, 12, 9, “CurveCut rc”); rc.display(); cout << “the area of ” << rc.getName() <<” is: “<< rc.area(); cout << “the perimeter of ” << rc.getName() << ” is: “<< rc.perimeter(); d = rc.distance(c); cout << “\nThe distance between rc and c is: ” <<d; // Using array of
Shape pointers: Shape* sh[4]; sh[0] = &s; sh[1] = &a; sh [2] = &c; sh [3] = &rc; sh [0]->display(); cout << “\nthe area of “<< sh[0]->getName() << “is: “<< sh[0] ->area(); cout << “\nthe perimeter of ” << sh[0]->getName () << ” is: “<< sh[0]->perimeter(); sh [1]->display(); cout << “\nthe area of “<< sh[1]->getName() << “is: “<< sh[1] ->area(); cout << “\nthe perimeter of ” << sh[0]->getName () << ” is: “<< sh[1]->perimeter(); sh [2]->display(); cout << “\nthe area of “<< sh[2]->getName() << “is: “<< sh[2] ->area();
cout << “\nthe circumference of ” << sh[2]->getName ()<< ” is: “<< sh[2]->perimeter(); sh [3]->display(); cout << “\nthe area of “<< sh[3]->getName() << “is: “<< sh[3] ->area(); cout << “\nthe perimeter of ” << sh[3]->getName () << ” is: “<< sh[3]->perimeter(); cout << “\nTesting copy constructor in class CurveCut:” <<endl; CurveCut cc = rc; cc.display(); cout << “\nTesting assignment operator in class CurveCut:” <<endl; CurveCut cc2(2, 5, 100, 12, 9, “CurveCut cc2”); cc2.display(); cc2 = cc; cc2.display(); #endif } // END OF FUNCTION run
What to Submit for Exercise A? 1. As part of your lab report (PDF file) submit: Copy of your complete source codes (.cpp and .h files), and the program output showing your code of this exercise works. 2. A zipped file with source file: All .cpp and .h files Exercise B: Templates in C++ (10 marks) Read This First: What is a Template Function? A template function is a function that one or more of its arguments types, and/or its return type are defined in a generic format that can be substituted with almost any actual built-in or user-defined type.
These substitutions and creation of an instance of function is called instantiation of a template function. In the following example, function swap has been declared as a template function: // function prototype template void swap (T* a, T* b); //function definition template void swap (T* a, T* b){ T temp ; temp = *a; *a = *b; *b = temp; } The keywords in this code are bold. The remaining parts of the code are similar to regular C++ functions.
As mentioned earlier, this generic or template definition, can be instantiated with different types. For example, the following code shows how the template function swap has been instantiated, and how its first call receives two integer pointers; while its second instance receives two float pointers. For more details about template function please refer to your lecture notes (slides) or a textbook such as C++ Primer, the latest version. void main() { int n = 8, m = 6; float x = 4.5, y =5.5; swap (&n,&m); // instantiation for swapping two integer swap (&x, &y); // instantiation for swapping two float } What is a Template Class? Templates classes are usually used to design and develop container data structures, such as queues, stacks, linked lists, vectors and etc.
The template and non-template classes behave essentially the same. Once the template class has been made known to the program, it can be used as a type specifier, the same as a nontemplate class. However, the only difference is that the use of a template class name must always include its parameter list enclosed by angle brackets (except within its own class definition).
The following examples show the definition of a template class called Vector, and one of its member functions, getValue(): template class Vector { public: Vector(int s); ~Vector(); T getValue(int elem); private: T *array; int size; }; template T Vector::getValue (int elem) { return array[elem]; } Sometimes a template function cannot provide a correct instance of the functions. In these cases, you should write a specialization of the function.
For more details about the specialization of a template function, please refer to your lecture notes. If there is a need to a specialization of a member function, it must be defined in the same file, after the definition of the template function. What is Template Class Instantiation? A template class can be instantiated by appending the full list of actual parameters enclosed by angle brackets to the template class name.
The following example shows how the template class Vector can be instantiated. int main() { Vector x (3); Vector y (40); … return 0; } What is an Iterator? In general, an iterator is an object that provides a general method of successively accessing each element of a container type such as vectors or lists. In other words, it’s an object that enables a programmer to traverse linear containers such as arrays, vectors and lists.
For example, we can write an iterator class called VectIter, that provides overloaded operators to allow access to the elements of the Vector. Assume we have an object of VectIter called iter that initially is associated with the first element of an object of class Vector called myVector, then a statement such as: cout << iter++; displays the value of the first element of the vector and then advances the iterator object to the next object in the second element of the vector.
This means that you must overload operator ++ (postfix) in the class IntVectorIter for this purpose. Or, a statement such as: cout << ++iter; should advance the iterator object to the next element of the vector and then display the value of the previous element. This means that you should overload operator ++ (prefix) in the class IntVectorIter for this purpose.
Similarly, the following statement: cout << iter–; displays the value of the current element of the vector and then moves the iterator object to the previous object in the vector. It means that you should overload operator — (postfix) in the class IntVectorIter for this purpose.
What to Do for Exercise B: Download files mystring2.h, mystring2.cpp, and iterator.cpp from D2L. Read the iterator.cpp carefully to understand the detail of the code in this file. Now, you should: 1. Write the definition of operator functions declared in class Vector, and class VectIter that is embedded in the class Vector. 2. Convert the Vector class to a Template class. A class that virtually can create vectors of different types. 3. The given main function is partially compiled by the conditional compilation directives. Means a major segment of the code is commented out by using conditional compilation directive #if 0.
Once you are done with the conversion of the class vector to a template class, change the #if 0 directive to #if 1 to include this part for compilation, and test your template class Vector and its iterator operators for data type: int, Mystring, and char*. 4. Make sure your function ascending_sort in the file iterator.cpp works properly for all data types. 5. Note: you may need to make other changes to the given source code to get your template class to work perfectly.
What to Submit: Submit your source files iterator.cpp, mystring2.h and mystring2.cpp as part of your lab report (PDF file), the program output that shows that your program works, and a zipped file that contains ALL your source files for exercise B. Exercise C (20 marks) The class LookupTable in this exercise is very similar to class DictionaryList in one of the previous labs with a few exceptions that will be explained in the following section.
What to Do 1. Download files customer.h, customer.cpp, lookupTable.h, mainLab3ExC.cpp from D2L, and use your source codes mystring2.h and mystring2.cpp, from exercise B. 2. Compile, run, and observe the program output. Up to this point, the given code only works for objects of class Customer and keys of integer type. But our intention is to convert the entire code to generic type, in a way that being able to have lookup table that can have different type of keys (usually integer, long, or C-string type, or Mystring type) and virtually data of any type. 3. Class LookupTable is similar to DictionaryList, with some exceptions: – First, the data member keyM and DatumM are now placed in a struct called Pair.
Please notice that there is a constructor defined for Pair. – The second difference is that an iterator class is embedded in the LookupTable. The job of this class is to manage a set of overloaded operators. 4. Modify the code and convert the LookupTable class to a template class. 5. Modify the global functions try_to_find() and print() to template functions.
6. Compile and test your program for creating objects of LookupTable. 7. Uncomment the code related to testing objects of LookupTables of <int, Mystring>. 8. Compile and test your program to create objects of LookupTable<int, Mystring> 9. Uncomment the code related to testing LookupTable <int, int>
10. Compile and test your program to create objects of LookupTable<int, int> What to Submit: – As part of your lab report (pdf file): o Copy of your source code: LookupTable.h, mainLab3ExC.cpp. o The programs output that shows your program works. – A zipped file that contains ALL your source files for exercise C (.cpp and .h)