Labs for CS 1037a

Class "DynArray"

GOAL: Switch from direct implementation of dynamic arrays in lab 2 to using "wrapper" classes (e.g. "DynArray") hiding dynamic memory allocation operations inside their member functions (e.g. constructor/destructor/resize). You will also use a new type of objects: "Cards".

  1. Create a new empty "Console Application" project

    Follow details of excercise 1 from lab 1. In particular, make sure to uncheck "Create directory for solution" inside "New Project" window, and select "Empty project" inside "Application Settings". You can choose "lab03" as a name for this new project.

  2. Adding existing files into your project

    Copy all files and directory cards_bmp from lab03Files.zip directly into lab03 directory created by the developer studio. Use "Solution Explorer View" (Fig.2B) to check that the developer studio can see these files in the project directory. Include all files into your project by right-clicking on their names inside "Explorer View" and selecting "Include In Project". Check that classes "Point", "Rect", "Card", "VisualCard", "ImageCard", "DynArray", and their attributes (member functions and variables) appear in the "Class View" (Fig.2A). Also check that "main" and drawing functions from cs1037lib appear in the list of "global functions" (Fig.2A).

    (2A) Class View (2B) Explorer View
    @ @
  3. From "VisualCards" to "Image Cards" (Inheritance and Overwriting)

    The included project in main.cpp is a working implementation of one of the last excercises from lab 2 (exercise 12): it uses a dynamic array "c[i]" of pointers to dynamic objects (see Fig 4A below). The objects are displayed in the window. Instead of rectangles, however, the current project uses "Visual Cards" objects, as shown in Fig.3A-B. Compile and test-run the project. You can press a digit-key to change the number of cards (the size of the dynamic array). You can also left-click on each card to see its "face" side (suit and denomination) and right-click to delete a card.

    "VisualCards" are objects similar to rectangles, but they also have suit and denomination and they can be in one of two states: "face up" or "face down". Check code for draw_cards() in "main.cpp". It uses member function drawAt() for each "VisualCard" object. Look at the code for member function drawAt() (see VisualCard.cpp). As in the previous labs, global functions from cs037lib-window are used to draw a rectangle representing a card. Depending on the state of a boolean flag m_face_up (see VisualCard.h), function drawAt() displays or hides text representing the card's suit/denomination.

    When you click inside the window (Fig.3B) your mouse-input is captured inside the "while-loop" in function "main" and global function left_click() (or right_click()) is called. Study the code of these functions at the bottom of main.cpp and understand how left-clicking toggles the appearance of the cards on the display (between "face-up" and "face-down").

    (3A) Console (3B) Visual Cards (3C) Image Cards
    @ @ @

    Your project files should include implementation of ImageCard, another card class derived from VisualCard. Thus, ImageCard inherits all functionality of VisualCard. Class ImageCard also overwrites function drawAt(...) so that ImageCard's face and back sides are drawn more realistically. Each ImageCard contains images of face and back sides that are initialized from a collection of bmp files inside subdirectory cards_bmp (should be inside your project's directory). Each "Image Card" object occupies relatively large amount of memory, thus these objects should be used with certain care. This provides an additional motivation for the dynamic allocation of card-objects (as memory can be used only exactly when required).

    Replace the name of class VisualCard in the declation of double-pointer 'c' by the class name ImageCard. Also, switch class names used inside function reset_cards. Compile and test run your code. Your program should work as before (test card toggling and deleting), except for better graphical visualization of cards (Fig 3C).

  4. Class "DynArray" (array "wrapper")

    In this excercise you should understand and lightly modify an existing implementation of class DynArray. You might be exposed to a relatively new syntax (e.g. for overloaded operator[]) and it is a good idea to have a close look. The main goal, however, is to get used to an idea that dynamic arrays can be build inside objects. Such an object can be described as a "wrapper" managing an internal (hidden/private) array while providing a natural (public) "interface" for accessing the array's elements. In particular, each "DynArray" object contains member variables m_container (a pointer to a dynamically allocated array) and m_size (number of allocated elements). Note that the existing project uses doublepointer "c" to store the adress of a dynamically allocated array (of pointers to cards), see fig.4A. In this exercise you should store pointers to cards inside "DynArray" object "c", as illustrated in fig.4B.

    (4A) Explicit dynamic array (4B) Using "DynArray" object (4C) Conceptual view on "DynArray"
    @ @ @

    Compile and test-run your project. It should work as before.
    Bottomline: Conceptually, any DynArray object is basically an array (see fig 4C). In particular, DynArrays are as easy to use as standard static arrays, but unlike static arrays, DynArray can change size at any time in your program. Implementation of class "DynArray" hides (inside code for constructor/destrructor and resize functions) many memory menagament operations for the dynamic array "m_container". A user of a DynArray does not need to worry about them. .