In this lab, you will refactor the code you wrote last week to conform to an object-oriented style, and to behave more like idiomatic C++. While we can write C in C++ for the most part, C++ offers additional functionality, and there are accepted best practices. In addition to this refactoring, you will find some bugs in an array-based implementation of a list. After completing this lab, you should:
class
in C++, and refactor existing C code to be able to operate more like C++ code.new
to allocate memory, as opposed to malloc
.You may work with a partner for this lab. If you choose a partner, both members must contribute to the same work. That is, you cannot simply divide the lab in half, as everyone is responsible for all the content. Instead, you should use a pair programming style. In pair programming, one person acts as a driver, who takes control of the keyboard. The other person acts as a navigator, who reviews what the driver writes and offers advice. Oftentimes, the driver is occupied with details of the problem (e.g., variables, control flow, etc.), whereas the navigator is concerned with bigger-picture problems (e.g., functions, design, interactions). This works well for problems which are simply too large to fit into one person's head. If you're unfamiliar with the concept of pair programming, you may wish to watch this video on the topic.
With pair programming, oftentimes it works best if both participants are of approximately the same skill level. Generally, if the disparity in skill is large, the end result is frustrating for both parties - it really only works when both parties operate at approximately the same speed. With this in mind, you should select someone of approximately the same skill level.
This C++ Tutorial
offers a lot. Much of the basics are review, given that C++ is a
superset of C. If you are solid on C, you can skim through the Basics,
Functions(I), Arrays, and Pointers. Just note the new bool
data type.
As for new material, you should read the Classes(I) tab in the tutorial. For those with the textbook, Chapters 2.1 - 2.4 in the Dale book cover this material.
The Rectangle
examples that we covered in lecture should prove
very useful in understanding this assignment. Below are the relevant files.
I would suggest opening
the C ones in one browser window (three tabs) and the other in another window
(three tabs). Then you can put the analogous files side by side and truly
see the differences (as well as similarities).
-bash-4.2$ cd -bash-4.2$ pwd /cs/student/yourusername -bash-4.2$ cd cs24 -bash-4.2$ pwd /cs/student/yourusername/cs24 -bash-4.2$ mkdir lab3 -bash-4.2$ cd lab3 -bash-4.2$ pwd /cs/student/yourusername/cs24/lab3
Now copy over the files for this week.
They are kept in the directory: /cs/student/kyledewey/cs24/labs/3
-bash-4.2$ cp /cs/student/kyledewey/cs24/labs/3/* .
Note that there is a '.'
at the end of that line. cp
means copy.
/cs/student/kyledewey/cs24/labs/3/*
means all of the files contained
in the directory /cs/student/kyledewey/cs24/labs/3
. The '.'
means to
copy from that location to the current location.
Now check to make sure the copy worked correctly:
-bash-4.2$ ls
You should see a set of files listed that will be used for this warm-up.
You must also copy of the *.c
and *.h
files from
last week, like so:
-bash-4.2$ cp ../lab2/*.c ../lab2/*.h .
The file reading_questions.txt
contains a series of questions
you must answer. More instructions are in that file.
In this portion, you will refactor some C code to behave more like idiomatic,
object-oriented C++ code. I will step you through Card.cpp
,
and you will have to implement Deck.cpp
yourself. The files
Card.h
and Deck.h
have been provided for you, so
you know exactly what needs to be implemented in Card.cpp
and
Deck.cpp
.
For this portion, you should assume that you need no error checking.
This is in contrast to the previous week, where adding error checking was
a potentially significant portion. Part of this is because we can no longer
signal errors in certain contexts, as with the old make_card
.
Another part is that certain kinds of errors are no longer possible.
For example, with the Deck
class, we can only create decks
through the constructor, which is assumed to be correct. We also have
things set that you cannot mutate cards once created, so whole classes of
errors are now impossible.
In multiple places, you will need to modify code that was previously provided for you in order to get things to compile. This is expected.
Card.cpp
problemhelpers.c
to be Card.cpp
:
-bash-4.2$ cp problemhelpers.c Card.cpp
#include
s to be C++ style.
For example, #include <stdio.h>
becomes #include <cstdio>
.
Deck
class you will implement in the next part.
Card::
before each of the function (now method) names
(after the return type) This tells the compiler
that the method you are implementing is from the class Card, which allows
the method to access the instance variables.
"card"
struct
,
replace that with "Card"
.
card*
argument (which you can still access using the this
keyword).
For example, with compare
, the first card
argument argument should go away, as it is now implicitly the object
on which the compare
method was called. That is,
this
is implicitly the first argument.
make_card
to be a constructor.
Make sure you remove the malloc
line, because it is called
along with new
. The new
call is not inside
the constructor.
get_suit
. Remember to place
Card::
in between the return type and the method name.
malloc
calls with new
calls.
While malloc
can still be used in C++ programs, it is
generally good practice to use new
instead.
print
function.
Previously, code just printed out the individual fields whenever
necessary. Now that we have methods, this functionality should be
put right onto the Card
class.
Once you have finished, you are ready to compile. But wait! You
only have one file, and it doesn't have a main
!?!?
How can you compile? Well, there is a way to compile only one file
when your program is not finished yet. This doesn't allow you to
test it fully, but it does allow you to get a lot of things fixed
that cause compiler errors. The key is the -c
flag.
Use that flag now, along with clang++
because we are
using C++:
-bash-4.2$ clang++ -c Card.cpp
If it says that an instance variable was not defined, you probably forgot
the Card::
before the method name.
Deck.cpp
The Deck.h
header file has been provided for you.
Looking closely at that, implement Deck.cpp
using the
same instructions as with Card.cpp
. Note one large difference with Deck.h
: The
array of Card
objects is now an array of Card
pointers. This is because of limitations in how you can call new
with arrays of objects. When it is an array of pointers, you
can call the Card
constructor individually on each card.
If you make it an array of Card
objects, all cards will
be created using a constructor with now arguments (the default constructor).
Then you have to take a second pass and initialize them all. Your
Deck
constructor will create the standard deck of cards.
main.cpp
Now you need to change over problemmain.c
. It is currently
implemented in C.
problemmain.c
to be main.cpp
#include
s. First replace the
existing C library includes with the C++ way of including those C libraries
(cstdio
rather than stdio.h
). Then add
using namespace std;
where stdlib
used to be
(you no longer need stdlib
). Finally, add the
#include
s for Card.h
and Deck.h
,
and remove the #include
for problemhelpers.h
.
There is also an equivalent to #include <stdio.h>
-
it is #include <iostream>
. But, since we aren't using
any C++ methods for performing I/O (reading from a file, reading from
the keyboard, or print to the screen), we don't need it.
Card
and Deck
rather than card
and deck
new
instead of malloc
Card
constructor rather than make_card
struct
, you
will need to call the printCard
method of the
Card
class. Look at my earlier example in the code for
how to do that.
-bash-4.2$ clang++ main.cpp Card.cpp Deck.cpp
Your next task is to find the bugs in the AList
class through
testing alone. If you need to, go back and reread the relevant portion of
the first lab, which described different ways of
finding bugs. In this case, we are looking for a bug
in the implementation of a class with well-defined inputs and behaviors.
You are not trying to anticipate all of the different errors a user
could make.
This class is a list backed by an array. You may insert an element anywhere in the list, and the rest of the elements will be pushed later in the list. When you are testing a program of this nature, for each function, you need to look at different valid and invalid inputs. Think about a list of 10 elements. What are the valid inputs, and what are the invalid inputs? You need to test at the boundary between the invalid and valid ones - two tests at each boundary. You can also test lists of different numbers of elements, including an empty list, a list with one element, and a list with many element.
In order to create test cases, instead of running the program and testing
it interactively, you will place your test cases in main. We have provided
a starting main
for you - test_list.cpp
. This does not trigger any error
conditions. Your job is to add code to that file until it triggers an
error message. Once you find that error message, it will tell you how to
save your .cpp
file. There are two things you need to do at this point:
-bash-4.2$ cp test_list.cpp bug_[n].cpp
To compile and test the code:
-bash-4.2$ clang++ test_list.cpp AList.o -bash-4.2$ ./a.out
One word of warning: We will change the printf
's in AList.o
in the test
environment, so do not hard-code any of the printf
's into the file containing main
.
You will receive no points.
There are four bugs in all. If you cannot find all the bugs, you
should submit an empty file, perhaps made by using touch
(described in the first lab).
First, fill out the required fields in the provided README.txt
file.
Once you have filled this in, you may submit everything with the following command:
-bash-4.2$ turnin lab3@cs24 README.txt reading_questions.txt Card.cpp Card.h Deck.cpp Deck.h main.cpp bug_1.cpp bug_2.cpp bug_3.cpp bug_4.cpp
All content was graciously provided by Professor Diana Franklin, with slight formatting-related adaptation.