Here is the code for Coad & Nicola's Count, IntegerCount, and for our Integer_Count_With_Base and Multiple_Count. Included are also some utility functions, and a main function. This code includes a working demo (specified in main()). Just compile the code to check it out.
/************************************************************* * You can compile this file with: g++ filename.cc * ************************************************************* */ #include#include #include #include #include #include #include /* Function prototypes **************************************/ int power(int base, int n); char dtoc(int digit); /* Classes **************************************************/ template class Count { public: // Constructors/destructors Count() { } virtual ~Count() { } // Implementors virtual void increment() = 0; virtual void decrement() = 0; void reset(){value = reset_value;} // Accessors Count_Type get_value() { return value; } void set_value(Count_Type new_value) { value = new_value; } Count_Type get_reset_value() { return reset_value; } void set_reset_value(Count_Type new_value) { value = new_value; } // Human interaction accessor Count_Type get_display_value() { return value; } protected: // Data members Count_Type value; Count_Type reset_value; }; class Integer_Count : public Count { public: // Constructors/destructors Integer_Count() { reset_value = 0; reset(); } Integer_Count(int new_value) { reset_value = 0; value = new_value; } ~Integer_Count() { } // Implementors void increment(); void decrement(); char* asBase(int number_base); }; class Integer_Count_With_Base : public Integer_Count { public: // Constructors/destructors Integer_Count_With_Base() { reset_value = 0; reset(); base = 10; next = NULL; } Integer_Count_With_Base(int new_value) { reset_value = 0; base = 10; if ((value > base-1) || (value < 0)) value = reset_value; else value = new_value; next = NULL; } Integer_Count_With_Base(int new_value, int new_base) { reset_value = 0; if ((new_base > 37) || (new_base < 0)) base = 10; else base = new_base; if ((value > base-1) || (value < 0)) value = reset_value; else value = new_value; next = NULL; } ~Integer_Count_With_Base() { } // Implementors void increment(); void decrement(); // Data members int base; Integer_Count_With_Base *next; }; // Integer_Count_With_Base member functions void Integer_Count_With_Base::increment() { if ((value + 1) == base) { reset(); if (next != NULL) { next->increment(); } else { cout << "increment: counter overflow" << endl; } } else { value++; } } void Integer_Count_With_Base::decrement() { if (value == 0) { value = base - 1; if (next != NULL) { next->decrement(); } else { cout << "decrement: counter underflow" << endl; } } else { value--; } } class Multiple_Count { public: // Constructors/destructors Multiple_Count(int baseNumber, int numberOfDigits); Multiple_Count(int baseNumber, int numberOfDigits, int initialValue); // Implementors void setvalue(int new_value); char *value(void); void increment(void) { digit[0].increment(); } void decrement(void) { digit[0].decrement(); } void add(Multiple_Count&); void subtract(Multiple_Count&); int valueBaseTen(void); // Data members Integer_Count_With_Base *digit; int base; int number_of_digits; }; Multiple_Count::Multiple_Count(int baseNumber, int numberOfDigits, int initialValue) { base = baseNumber; number_of_digits = numberOfDigits; digit = new Integer_Count_With_Base[number_of_digits]; assert(digit != 0); // set each count to point to the next one -- and // initialize it's value for (int i = 0; i < (number_of_digits - 1); i++) { digit[i].next = &digit[i+1]; digit[i].base = base; } digit[number_of_digits - 1].next = NULL; digit[number_of_digits - 1].base = base; // initial each digit to the initial value this->setvalue(initialValue); } Multiple_Count::Multiple_Count(int baseNumber, int numberOfDigits) { int initialValue = 0; base = baseNumber; number_of_digits = numberOfDigits; digit = new Integer_Count_With_Base[number_of_digits]; assert(digit != 0); // set each count to point to the next one -- and // initialize it's value for (int i = 0; i < (number_of_digits - 1); i++) { digit[i].next = &digit[i+1]; digit[i].base = base; } digit[number_of_digits - 1].next = NULL; digit[number_of_digits - 1].base = base; // initial each digit to the initial value this->setvalue(initialValue); } void Multiple_Count::setvalue(int value) { int quotient = 0; int remainder = 0; // initialize each count to its value in the correct base -- // the base element of the array contains the low order digit quotient = value; for (int i = 0; ((i < number_of_digits) && (quotient != 0)); i++) { remainder = quotient % base; digit[i].set_value(remainder); quotient = quotient / base; } if (quotient != 0) printf("Multiple_Count: not enough digits to hold entire value "); } char * Multiple_Count::value(void) { char *value_as_string = new char[number_of_digits]; assert(value_as_string != 0); for (int i = (number_of_digits-1); i > 0; i--) { if (digit[i].get_value() != 0) break; } for (int j = 0; i >= 0 && j < number_of_digits; i--, j++) value_as_string[j] = dtoc(digit[i].get_value()); value_as_string[j] = ' '; return(value_as_string); } int Multiple_Count::valueBaseTen(void) { int result = 0; /* cout << "number_of_digits = " << number_of_digits << endl; for (int i = 0; i < number_of_digits; i++) { cout << "digit[i].get_value() = " << digit[i].get_value() << endl; } */ for (int i = 0; i < number_of_digits; i++) result += (power(base, i)) * digit[i].get_value(); return(result); } void Multiple_Count::add(Multiple_Count& aMultiple_Count) { int addValue = aMultiple_Count.valueBaseTen(); Multiple_Count temp_Multiple_Count(10, aMultiple_Count.number_of_digits, addValue); while (temp_Multiple_Count.valueBaseTen() != 0) { temp_Multiple_Count.decrement(); this->increment(); } } void Multiple_Count::subtract(Multiple_Count& aMultiple_Count) { int addValue = aMultiple_Count.valueBaseTen(); Multiple_Count temp_Multiple_Count(10, aMultiple_Count.number_of_digits, addValue); while (temp_Multiple_Count.valueBaseTen() != 0) { temp_Multiple_Count.decrement(); this->decrement(); } } // Integer_Count member functions void Integer_Count::increment() { value++; } void Integer_Count::decrement() { value--; } /************************************************************* * power: raise base to n-th power; n >= 0 ************************************************************* */ int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; i++) p = p * base; return p; } /************************************************************* * dtoc -- returns a char corresponding to a number in up to * base 37. ************************************************************* */ char dtoc(int digit) { char digitSymbols[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; if ((digit >= 0) && (digit <= 36)) return(digitSymbols[digit]); else { printf("dtoc: digit is out of range -- returning 0 "); return(digitSymbols[0]); } } /* main *****************************************************/ main() { // Create a multiple count object in base 10 with four digits Multiple_Count first(10,4); // Create a multiple count object in base 2 with 8 digits, // initialized to 15. Multiple_Count second(2,8,15); int i; cout << endl << "MULTIPLE DIGIT COUNTER DEMO" << endl; cout << endl << "First value " << first.value() << endl; cout << endl << "Second value " << second.value() << endl; first.setvalue(5); // Load 5 into first for (i=0; i < 123 ; i++) first.increment(); // Add in 123 cout << endl << "First value " << first.value() << endl; cout << endl << "Second value " << second.value() << endl; first.subtract(second); // Subtract second from first cout << endl << "First - second " << first.value() << endl; second.add(second); cout << endl << "Second + second " << second.value() << endl; }