Lab 8 Preparing to Ship Sheared Sheep Introduction ============ In the previous lab, we practiced sorting arrays. This time we are going to practice using classes and objects. The next, and final, lab will see the construction of a large scale application which will use both classes and sorting techniques. Lab 8-1 (Guided) ================ When we last left our intrepid heroes, they had just given the Etruscan programmers the task of figuring out how to store complex information in a program. Namely, they wanted to be able to store records for an entire sheep, and to sort the sheep so they could ship the sheep to where they need to go. The ancient programmers worked hard! They sent emissaries out into the world and traveled to the corners of the Mediterranean. While the travelers were gone, one of their programmers discovered that he could use multiple arrays to store complex records, but this proved to be very unwieldy. When he tried to sort them, everything fell apart. So, they waited until their brethren returned. Sadly, of the 4 that left, only 1 returned. No one knows what became of the other 3 programmers, but there is a very ancient line of people on the Isle of Crete who have a strange obsession with LISP, so we like to think that at least one of them survived. At any rate, one of them did make it back. He had been to Greece and he had heard a teacher by the name of Socrates speaking about something called the "Theory of the Forms*." In this theory, Socrates taught that everything in the world fit into a hierarchy, where each layer of the hierarchy represented different levels of abstraction. Thus people could speak of "Tree" as an abstract and see a specific tree as a shadow of "Tree". At first the other programmers thought that the young man was insane, which he may well have been, but that isn't the point. The point is that they soon realized that the ability to encapsulate ideas into abstractions was the answer they sought. They could write a small piece of code which contained all the information of the sheep's record, and then they could add behavior to that. Even better, they would be able to create a special container which they could store the sheep objects in. This container would represent the ship, and they could use this abstraction to think in terms of what the problem actually was. Rather than putting 5 records at some index into dozens of different arrays, they could think of "ship.loadSheep(sheep)" which was a lot clearer as to its intent. So they set out to learn what each of these containers should do. Their initial attempts were terribly complicated as they made the common mistake of trying to implement everything that went into making a ship a ship and a sheep a sheep. Surely ships and sheep could be expressed more easily. Eventually, one of the programmers had a break through. "My brothers! Here me!" (The rest of the team snickered at his purple prose, but they listened.) "Why don't we just implement the parts of the ship and sheep we are interested in?" The rest of the team thought this was a bangup idea, and so they decided on the following items for the ships: Data ---- A list of sheep. There can be at most 10 sheep in a ship. The number of sheep currently on the ship. Behavior -------- load a sheep onto the ship unload a sheep from the ship count the sheep print out the list of sheep determine if the ship is full or not. The team who was working on the sheep came up with the following items for the sheep. Data ---- Sex (M or F) Nationality (Etruscan, Jewish, or Greek) Destination (Any country in the world) Cost (Sistersi, stored in Indian number format) Shearing Status (has the sheep been sheared or not) Color (Any color) Behaviors --------- The ability to get or set all of the above attributes. The ability to pretty print the sheep's data. (a print sheep function) The ability to convert the sheep's data into a string. Having congratulated themselves on a good design, they set out to build the system. * For a treatment of Socrates's theory, take a look at "The Republic" (most notably the allegory of the cave) and Meno. You can get both online for free as the copyright expired over a thousand years ago. Head over to http://www.gutenberg.net for enlightenment. You'll want to search for "Plato" as the author because Socrates was the teacher, and Plato wrote down what Socrates said. Procedure ========= We will follow along with the first part of the system, which is the construction of the ship. The programmers decided that until they had the sheep class ready to go, they would implement the sheep as integers. They came up with the following header which they put into a file called sheepShip.h: -- Begin sheepShip.h -- // A small class for the storage of sheep on a ship. #ifndef SHEEPSHIP_H #define SHEEPSHIP_H class sheepShip { public: // Constructors sheepShip(); // Destructors ~sheepShip(); //methods //puts a sheep on the ship bool loadSheep(int sheep); //unloads a single sheep from the ship int unloadSheep(); //returns the number of sheep on the ship int sheepCount(); //prints the list of sheep on the ship void printSheep(); //returns true if the ship is full, false otherwise bool isFull(); private: int sheepHold[10]; int count; }; #endif -- end sheepShip.h -- The implementation file was placed into a file named sheepShip.cpp: -- begin sheepShip.cpp -- #include #include "sheepShip.h" //constructor sheepShip::sheepShip() { //the ship starts with no sheep count = 0; } //destructor sheepShip::~sheepShip() { //do nothing (for now) } //puts a sheep on the ship bool sheepShip::loadSheep(int sheep) { //full sheep ship! Ship it out! if(count == 10) return false; sheepHold[count++]=sheep; return true; } //unloads a single sheep from the ship int sheepShip::unloadSheep() { //empty hold! No sheep if(count==0) return 0; //unload and return the sheep return sheepHold[--count]; } //returns the number of sheep on the ship int sheepShip::sheepCount() { return count; } //prints the list of sheep on the ship void sheepShip::printSheep() { int i; for(i=0; i #include "sheepShip.h" using namespace std; int main(void) { int sheep; sheepShip ship; //fill up the ship while(!ship.isFull()) { //get a sheep from the user cout << "Sheep: "; cin >> sheep; //load the sheep on the ship ship.loadSheep(sheep); //print the current number of sheep cout << "There are " << ship.sheepCount() << " sheep on the ship." << endl; } //print the shipping manifest cout << "Shipping Manifest" << endl; ship.printSheep(); //unpack the ship cout << endl << "Unloading Order" << endl; while(ship.sheepCount()) { sheep = ship.unloadSheep(); cout << sheep << endl; } } --end shipTest.cpp-- Finally they constructed a makefile to ease the building process: --begin Makefile-- all: shipTest shipTest: sheepShip.o shipTest.o g++ -o shipTest shipTest.o sheepShip.o shipTest.o: shipTest.cpp g++ -c shipTest.cpp sheepShip.o: sheepShip.cpp sheepShip.h g++ -c sheepShip.cpp --end Makefile-- Your first task is to create all the files listed above and then get it working. Once you're able to run shipTest, take a moment to pause and reflect on how this program works. Look at it until you understand every last peace of it. You'll have to, because in the next section, you will be altering it! Lab 8-2 (self) ============== We have accomplished half the task before us. We have a ship class and ship objects. Now we have to modify all this to handle sheep correctly. 1. Create a sheep class. The class definition and implementation is up to you, but it should only contain the features described in lab 8-2. 2. Modify the sheepShip so that it stores sheep. Note that you'll have to include sheep.h in your header and in your implementation file. Also, you'll have to alter the following functions (both prototypes and definition): loadSheep unloadSheep printSheep 3. Modify the shipTest program so that instead of inserting and printing integers, it inserts and prints sheep. Also, you'll have to make it read in details about the sheep. So the code will get just a little bit longer. Hints ----- - Try to identify where you want to pass objects by references. Also, consider writing your own copy constructor. - The sheep class is very similar, in nature at least, to the phone records we did in class. - You'll also have to modify the makefile to be able to use the sheep. You'll want to add a sheep.o entry.