LINKÖPINGS UNIVERSITET Department of Computer and Information Science Software and Systems Tommy Olsson 2015-08-17 Computer examination in TDDD38 Advanced Programming in C++ Exam code: DAT1 Date: 2015-08-19 Time: 14-19 On duty: Tommy Olsson, 28 1954 Teacher on duty will visit the locations approximately once every hour, and is otherwise only to be called upon for urgent matter, for example computer system problems. Administrator: Anna Grabska Eklund, 28 2362 Means of assistance: An English-* vocabulary may be brought to the exam. cplusplus.com Reference, se instructions for how to browse. Scrap paper and pen is allowed. No other means of assistance (printed or electronic) are allowed. Grading: Each theory question is worth 1 credit, each programming problem 5 credits; total 25: 0-10 for grade U/FX, 11-14 for grade 3/C, 15-18 for grade 4/B, and 19-25 for grade 5/A. Instructions: Don’t log out at any time during the exam, only when you have finished. Given files are found in subdirectory given_files (write protected). Files for examination must be submitted via the Student Client, see separate instructions! In case names for program entities are specified, use those exactly as given. When using standard library components, such as algorithms and containers, try to chose “best fit” regarding the problem to solve. Avoid unrelated/unnecessary computations and unnecessary data structures. C style coding may cause point reduction when there are C++ alternatives. Follow specifications – design with care – use C++ properly! Good luck! TDDD38 Advanced Programming in C++ 2 (6) Theory questions Copy THEORY.TXT from directory given_files to the login directory: cp given_files/THEORY.TXT . Note trailing period. Fill in your personal data at the top of the file, and give your answers to the theory questions below in that file. 1. When initializing a data member of a class in a constructor one can either use a member initializer, or use assignment within the constructor body. Give differences, restrictions, guidelines, etc., for these two ways of initializing class data members. ❏ 2. What makes a class abstract? Give at least one distinguishing characteristics that abstract classes have in comparison to nonabstract classes. ❏ 3. What is a function try-block? A function try-block may be of extra interest when used in a constructor. How is that? ❏ 4. Explain the concepts static type and dynamic type. ❏ 5. Some operators can only be declared as a non-static member function. Which? Also, give a good reason for this. ❏ TDDD38 Advanced Programming in C++ 3 (6) Programming problems 6. Copy file program6.cc from given_files. The file contains a given interface class Serializeable, and some instructions about testing. Walking paths, such as pavements, often have a surface of some kind of blocks, for example bricks, pre-cast concrete blocks, or blocks made of rock. Design a polymorphic class hierarchy for such blocks, with an abstract base class Paver, and three direct concrete subclasses Brick, Concrete and Rock. • Paver shall store colour (string, for example ”Grey”), weight (double) in kg, and size (string, for example ”25x12.5x4.5” for length, width and height) in cm. Paver shall have member functions get_colour(), get_weight(), and get_size() to return the corresponding value. When a Paver object is created, colour, size, and weight shall be given, thereafter never modified. • Brick have no specific data members or member functions, beside those in Paver. When a brick objects is created, colour, size, and weight shall always be given, no defaults. • Concrete also stores whether blocks are tumbled or not (bool). Tumbling give the blocks a more aged appearance. Default is not tumbled (false). Concrete shall have a specific member function is_tumbled(), to return true if tumbled, false if not. When a Concrete object is created, colour, size, and weight shall be given. If tumbling is not given, default is not tumbled (false). No modifications after initialization. • Rock also stores the kind of rock the block it is made of (string, for example ”Granite”, ”Slate” or ”Marble”). The colour for Rock is always ”Natural”. Rock shall have a specific member function get_kind() to return the kind of stone the block is made from When a Rock object is created, kind, size, and weight, shall be given, no defaults. Colour is always set to “Natural”. Copying, of any kind, is not to be allowed! Special member functions to be allowed, and the compiler can generate shall be defaulted; special member functions which are not to be allowed, and the compiler will generate shall be deleted; special member functions which are not to be allowed, and the compiler will not generate shall not be declared. No other functions than those mentioned above are allowed! Expected output from the program (according to specified test cases in the file): Brick: Yellow, 25x10x10 cm, 3.2 kg Concrete: Grey, 25x12.5x4.5 cm, 2.8 kg, not tumbled Concrete: Graphite, 30x30x6 cm, 6.7 kg, tumbled Rock (Granite): Natural, 15x15x10 cm, 10.5 kg This is to be achieved by deriving Paver from an interface class Serializable (skeleton given) with an pure virtual member function str(), which serializeable classes are to override, when required. For Brick and Rock, str() shall return colour,size cm, weight kg For Concrete, str() shall return colour,size cm, weight kg, [not] tumbled As you can see, “colour, size cm, weight kg”, is common for all Paver objects, and should be taken advantage of. Hint: using an std::ostringstream can be a handy way to create some of the output from str(). Design with care – use C++ well – keep with and enforce the given specifications! ❏ TDDD38 Advanced Programming in C++ 7. 4 (6) Write your code on a file named program7.cc. Please note! Standard library components shall be used whenever possible, and always try to find “best fit” and natural solutions. Avoid hand-written loops (for, while or do, including range for even if such could be a good alternative), use standard algorithms when suitable. If a user defined function is required, use lambda expression or function object, not normal function. Write a program to process files containing words (white-space delimited sequence of strings composed of characters a-z). An example input data file, words.txt, is given in the directory given_files. The program shall do the following, step by step, and in each step, no more, no less than what is specified! Mark the beginning of each step with a comment on the form // 1, // 2, and so on. 1) The name of the input file is to be given on the command line. a.out ~/given_files/words.txt Check that one command line argument is given. If not, print an error message and terminate the program ended. Open an input file stream for the file name given on the command line, and check that the file could be opened. If not, an error message shall be printed and the program ended. 2) Read the words from the file and store them in an std::vector, here called first vector. 3) Print the words in first vector to cout, each word followed by a space character. 4) Sort first vector so the words will be ordered by length, and in case of equal length, in alphabetic order. 5) Print the words in first vector to cout, each word followed by a space character. 6) Copy the words in first vector to another vector, here called second vector, but only one instance of each distinct word (that is, no duplicates in second vector); first vector shall not be modified. 7) Print the words in second vector to cout, using some suitable standard algorithm and a function object, named formatter, for formatting the output. For the given input file, words.txt, the output shall be as below, if three elements is to be printed on each line, and the field width is set to 10 (elements are right justified): fie zoo foobar zwieback foo dump gazonk fum fidamp allocate formatter shall be a template with one type parameter for the type of elements to be printed. In our case it’s string elements, but formatter shall work for all types with operator<< overloaded. When a formatter object is created, the output stream, the output field width for the elements, and how many elements on each line to output shall be given as arguments. Element values shall always be right justified within the output field. Note: The choice of algorithm to use can be crucial for how complicated formatter will be. ❏ TDDD38 Advanced Programming in C++ 8. 5 (6) Copy program8.cc from given_files to your working directory, add your own code. The given file contains a test program. Define a class Currency for handling currencies which have a currency unit and hundredths of that unit. Examples of such currencies are Swedish kronor, French francs and US dollars, which have the units kronor, franc, and dollar, respectively, and hundredths in form of ören, centimes and cents, respectively. An object of type Currency shall not store the kind of currency, only the values for the unit and the hundredths. The values shall be stored as two integers. An object of type Currency shall only be possible to initialize in two ways) examples are found in the given file): • no initialization values – unit and hundredths are both initialized to 0 • two initialization values – one for the unit and one for the hundredths Currency object shall be copyable and assignable. Overload: • operator+ for adding two Currency values, and a corresponding add-and-assign operator+=. • operator++, in both prefix and postfix form, to increment a Currency object by one hundredth. • operator<< for printing a Currency to an output stream. The hundredths shall be printed with two digits, for example 100.00 or 100.05 You may add more member functions, if useful and relevant. Hint 1: operator / and operator % for integer are useful when implementing += and +. Hint 2: Formatting currency value is easy, if you use the possibility to change the fill character of the stream you are writing to. char c = os.fill(’0’); // print os.fill(c); // save the current fill character and set a new, ’0’ // reset ❏ TDDD38 Advanced Programming in C++ 9. 6 (6) Copy program9.cc from given_files to your working directory, add your own code. Define a container type RAC (Restricted Access Container) to be used for storing elements of some type T in an internal std::vector. RAC shall have the following public member functions: • put() shall store an element in the RAC. The element is given as an argument and shall be inserted in the vector. • get() fetches an element from the RAC. The element is removed from the vector and returned. • clear() removes all elements from the RAC, that is, clears the vector. RAC shall be a template class with two template parameters, one for the type of the element to be stored, and one for an access policy. A RAC object shall be declared as follows: RAC<int, stack_policy> rac_stack; The RAC object rac_stack above can be used to store int objects, and the operations put and get is supposed to operate on rac_stack with stack semantics, that is, first-in-last-out. Define two access policy classes: • Stack_Policy – makes put () and get () operate on the same end of the vector; such a RAC will act as a stack (last-in-first-out). • Queue_Policy – put() will insert at one end of the vector, and get() will remove from the other end of the vector; such a RAC will act as a simple queue (first-in-first-out). The access policy classes shall be adaptable to the type of element stored in the RAC, and shall have two member functions: • insert() is to be used by RAC put() to insert an element in the vector, according to the access policy. Parameters as required. • remove() is to be used by RAC get() to remove an element from the vector and return it, according to the access policy. Parameters as required. A short program for testing the two policies is given. The code in main() shall not require any modifications. ❏