The second pouring puzzle solution implements the pour function using pass-by-pointer and creates the glasses array as an array of pointers on the heap with the new
operator. Beyond these two small differences, the two solutions are the same.
/* * Implements a single glass used in a water-pouring puzzle. * Each instance has a volume and amount. The class tracks the number of pours with a static variable. */ #include <iostream> using namespace std; class Glass { private: static int pours; // number of times water is poured from 1 glass to another int volume; // how much water the glass can hold int amount; // how much water is in the glass now public: Glass(int a_volume, int a_amount) : volume(a_volume), amount(a_amount) {} int getVolume() { return volume; } int getAmount() { return amount; } void display() { cout << amount << " / " << volume << endl; } static int getPours() { return pours; } void pour(Glass* from); };
static
variable, are private
; the member functions are public
. Except for the pour function, the class inlines all functions in the specification. The two "get" functions are examples of getter or accessor functions.
#include "Glass.h" #include <algorithm> // for the min function using namespace std; int Glass::pours = 0; // #1: initializes static data // Pour water from the source glass to the destination or this glass. void Glass::pour(Glass* source) // pour from one glass to another { pours++; // #2: increment the number of moves int space = volume - amount; // #3: space available in the "to" glass // #4: algorithm 1 ---------------------------------------------------------- /*if (space < source->amount) { source->amount -= space; amount = volume; // destination glass is now full // amount += space; // also works } else { amount += source->amount; source->amount = 0; // source glass is now empty }*/ // #5: algorithm 2 ----------------------------------------------------------- int transfer = min(space, source->amount); //int transfer = (space < source->amount) ? space : source->amount; // alternate amount += transfer; source->amount -= transfer; }
static
variable (the same syntax is used for both public
and private
variables). pours tracks the number of times the player pours water from one glass to another and acts as a move counter for the puzzle./* * Implements a simple puzzle whose goal is to divide 8 ounces of water between * three glasses so that at least one glass contains exactly 8 ounces. * The three glasses have different capacities: 3 oz., 5 oz., and 8 oz.; the game * begins with the 8-oz. glass full and the other two glasses empty. Divide the * water by pouring it between glasses. */ #include <iostream> #include "Glass.h" using namespace std; int main() { Glass* glasses[] { new Glass(3,0), new Glass(5,0), new Glass(8,8) }; // #1: create & init array /* * Loops until at least one glass contains precisely 4 oz of water. * Exits early if the player enters 4 at any prompt. */ while (glasses[1]->getAmount() != 4 && glasses[2]->getAmount() != 4) { for (int i = 0; i < 3; i++) // #2: display glasses { cout << "Glass " << i + 1 << ": "; glasses[i]->display(); } int destination; cout << "Pour TO glass: <1, 2, or 3; or enter 4 to quit>: "; cin >> destination; if (destination == 4) // end the puzzle early exit(0); int source; cout << "Pour FROM glass: <1, 2, or 3; or enter 4 to quit>: "; cin >> source; if (source == 4) // end the puzzle early exit(0); if (source > 0 && source <= 3 && destination > 0 && destination <= 3) glasses[destination - 1]->pour(glasses[source - 1]); // #3: pour water else cout << "0 < destination <= 3 AND 0 < source <= 3" << endl; } cout << "\n\nYou solved the puzzle in " << Glass::getPours() << " pours" << endl; // #4: the total # of pours for (int i = 0; i < 3; i++) // #5: final glass contents glasses[i]->display(); return 0; }
new
. To better support the pass-by-pointer, we replace the array of Glass objects with an array of pointers. Each pointer points to an instance of the Glass class instantiated one at a time on the heap. Changing objects to pointers implies that the arrow operator must replace the dot operator whenever we access a function or variable in one of the Glass objects.
static
variable pours, which counts how many steps were needed to solve the puzzle. Note that pours "belongs" to the class as a whole, so the program accesses it with a static
function, which also "belongs" to the class. Programs call static
functions with the class name and the scope resolution operator: Glass::getPours();.