You are on page 1of 59

Absolute C++ 5th Edition Savitch

Solutions Manual
Visit to download the full and correct content document:
https://testbankdeal.com/download/absolute-c-5th-edition-savitch-solutions-manual/
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Chapter 7
Constructors and Other Tools
Key Terms
constructor
initialization section
default constructor
constant parameter
const with member functions
inline function
static variable
initializing static member variables
nested class
local class
vector
declaring a vector variable
template class
v[i]
push_back
size
size unsigned int
capacity

Brief Outline
7.1 Constructors
Constructor Definitions
Explicit Constructor Calls
Class Type Member Variables
7.2 More Tools
The const Parameter Modifier
Inline Functions
Static Members
Nested and Local Class Definitions
7.3 Vectors – A Preview of the Standard Template Library
Vector Basics
Efficiency Issues.

1. Introduction and Teaching Suggestions


Tools developed in this chapter are the notion of const member functions, inline functions, static
members, nested classes and composition. A const member function is a promise not to change
state of the calling object. A call to an inline function requests that the compiler put the body of
the function in the code stream instead of a function call. A static member of a class is

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

connected to the class rather than being connected to specific object. The chapter ends with a
brief introduction to the vector container and a preview of the STL.

Students should immediately see the comparison of vectors to arrays and note how it is generally
much easier to work with vectors. In particular, the ability to grow and shrink makes it a much
easier dynamic data structure while the use of generics allows vectors to store arbitrary data
types. If you have given assignments or examples with traditional arrays then it may be
instructive to re-do those same programs with vectors instead.

2. Key Points
Constructor Definitions. A constructor is a member function having the same name as the
class. The purpose of a class constructor is automatic allocation and initialization of resources
involved in the definition of class objects. Constructors are called automatically at definition of
class objects. Special declarator syntax for constructors uses the class name followed by a
parameter list but there is no return type.

Constructor initialization section. The implementation of the constructor can have an


initialization section:
A::A():a(0), b(1){ /* implementation */ }
The text calls the :a(0), b(1) the initialization section. In the literature, this sometimes
called a member initializer list. The purpose of a member initializer list is to initialize the class
data members. Only constructors may have member initializer lists. Much of the time you can
initialize the class members by assignment within the constructor block, but there are a few
situations where this is not possible. In these cases you must use an initialization section, and the
error messages are not particularly clear. Encourage your students to use initialization sections in
preference to assignment in the block of a constructor. Move initialization from the member
initializer list to the body of the constructor when there is a need to verify argument values.

Class Type Member Variables. A class may be used like any other type, including as a type of
a member of another class. This is one of places where you must use the initializer list to do
initialization.

The const Parameter Modifier. Reference parameters that are declared const provide
automatic error checking against changing the caller’s argument. All uses of the const modifier
make a promise to the compiler that you will not change something and a request for the
compiler to hold you to your promise. The text points out that the use of a call-by-value
parameter protects the caller’s argument against change. Call-by-value copies the caller’s
argument, hence for a large type can consume undesirable amounts of memory. Call-by-
reference, on the other hand, passes only the address of the caller’s argument, so consumes little
space. However, call-by-reference entails the danger of an undesired change in the caller’s
argument. A const call-by-reference parameter provides a space efficient, read-only parameter
passing mechanism.

A const call-by-value parameter mechanism, while legal, provides little more than an annoyance
to the programmer.

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

The const modifier appended to the declaration of a member function in a class definition is a
promise not to write code in the implementation that will change the state of the class. Note that
the const modifier on the function member is part of the signature of a class member function
and is required in both declaration and definition if it is used in either.

The const modifier applied to a return type is a promise not to do anything the returned object to
change it. If the returned type is a const reference, the programmer is promising not to use the
call as an l-value. If the returned type is a const class type, the programmer is promising not to
apply any non-const member function to the returned object.

Inline Functions. Placing the keyword inline before the declaration of a function is a hint to the
compiler to put body of the function in the code stream at the place of the call (with arguments
appropriately substituted for the parameters). The compiler may or may not do this, and some
compilers have strong restrictions on what function bodies will be placed inline.

Static Members. The keyword static is used in several contexts. C used the keyword static
with an otherwise global declaration to restrict visibility of the declaration from within other
files. This use is deprecated in the C++ Standard.. In Chapter 11, we will see that unnamed
namespaces replace this use of static.

In a function, a local variable that has been declared with the keyword static is allocated once
and initialized once, unlike other local variables that are allocated and initialized (on the system
stack) once per invocation. Any initialization is executed only once, at the time the execution
stream reaches the initialization. Subsequently, the initialization is skipped and the variable
retains its value from the previous invocation.

The third use of static is the one where a class member variable or function is declared with the
static keyword. The definition of a member as static parallels the use of static for function local
variables. There is only one member, associated with the class (not replicated for each object).

Nested and Local Classes. A class may be defined inside another class. Such a class is in the
scope of the outer class and is intended for local use. This can be useful with data structures
covered in Chapter 17.

Vectors. The STL vector container is a generalization of array. A vector is a container that is
able to grow (and shrink) during program execution. A container is an object that can contain
other objects. The STL vector container is implemented using a template class (Chapter 16). The
text’s approach is to define some vector objects and use them prior to dealing with templates and
the STL in detail (Chapter 19). Unlike arrays, vector objects can be assigned, and the behavior is
what you want. Similar to an array, you can declare a vector to have a 10 elements initialized
with the default constructor by writing
vector<baseType> v(10);
Like arrays, objects stored in a vector object can be accessed for use as an l-value or as an r-
value using indexing.
v[2] = 3;
x = v[0];

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Unlike arrays, however, you cannot (legally) index into a vector, say v[i], to fetch a value or to
assign a value unless an element has already been inserted at every index position up to and
including index position i. The push_back(elem) function can be used to add an element to
the end of a vector.

Efficiency Issues for Vectors. Most implementations of vector have an array that holds its
elements. The array is divided into that used for elements that have been inserted, and the rest is
called reserve. There is a member function that can be used to adjust the reserve up or down.
Implementations vary with regard to whether the reserve member can decrease the capacity of a
vector below the current capacity.

3. Tips
Invoking constructors. You cannot call a constructor as if it were a member function, but
frequently it is useful to invoke a constructor explicitly. In fact this declaration of class A in
object u :
A u(3);
is short hand for
A u = A(3);
Here, we have explicitly invoked the class A constructor that can take an int argument. When we
need to build a class object for return from a function, we can explicitly invoke a constructor.
A f()
{
int i;
// compute a value for i
return A(i);
}

Always Include a Default Constructor. A default constructor will automatically be created for
you if you do not define one, but it will not do anything. However, if your class definition
includes one or more constructors of any kind, no constructor is generated automatically.

Static member variables must be initialized outside the class definition. Static variables may
be initialized only once, and they must be initialized outside the class definition.. The text points
out that the class author is expected to do the initializations, typically in the same file where the
class definition appears.
Example:
class A
{
public:
A();
. . .
private:
static int a;
int b;

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

};
int A::a = 0; // initialization

A static member is intended to reduce the need for global variables by providing alternatives that
are local to a class. A static member function or variable acts as a global for members of its class
without being available to, or clashing with, global variables or functions or names of members
of other classes.

A static member function is not supplied with the implicit “this” pointer that points to the
instance of a class. Consequently, a static member function can only use nested types,
enumerators, and static members directly. To access a non-static member of its class, a static
member function must use the . or the -> operator with some instance (presumably passed to
the static member function via a parameter).

4. Pitfalls
Attempting to invoke a constructor like a member function. We cannot call a constructor for
a class as if it were a member of the class.

Constructors with No Arguments. It is important not to use any parentheses when you declare
a class variable and want the constructor invoked with no arguments, e.g.
MyClass obj;
instead of
MyClass obj();
Otherwise, the compiler sees it as a prototype declaration of a function that has no parameters
and a return type of MyClass.

Inconsistent Use of const. If you use const for one parameter of a particular type, then you
should use it for every other parameter that has that type and is not changed by the function call.

Attempt to access non-static variables from static functions. Non-static class instance
variables are only created when an object has been created and is therefore out of the scope of a
static function. Static functions should only access static class variables. However, non-static
functions can access static class variables.

Declaring An Array of class objects Requires a Default Constructor. When an array of class
objects is defined, the default constructor is called for each element of the array, in increasing
index order. You cannot declare an array of class objects if the class does not provide a default
constructor.

There is no array bounds checking done by a vector. There is a member function,


at(index) that does do bounds checking. When you access or write an element outside the
index range 0 to (size-1), is undefined. Otherwise if you try to access v[i] where I is greater than
the vector’s size, you may or may not get an error message but the program will undoubtedly
misbehave.

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

5. Programming Projects Answers


1. Class Month
Notes:

Abstract data type for month.


Need:
Default constructor
constructor to set month using first 3 letters as 3 args
constructor to set month using int value : 1 for Jan etc

input function (from keyboard) that sets month from 1st 3 letters of month name
input function (from keyboard) that sets month from int value : 1 for Jan etc
output function that outputs (to screen) month as 1st 3 letters in the name of the month (C-
string?)
output function that outputs (to screen) month as number, 1 for Jan etc.
member function that returns the next month as a value of type Month.

.int monthNo; // 1 for January, 2 for February etc

Embed in a main function and test.

//file: ch7prb1.cpp
//Title: Month
//To create and test a month ADT

#include <iostream>
#include <cstdlib> // for exit()
#include <cctype> // for tolower()

using namespace std;

class Month
{
public:
//constructor to set month based on first 3 chars of the month name
Month(char c1, char c2, char c3); // done, debugged
//a constructor to set month base on month number, 1 = January etc.
Month( int monthNumber); // done, debugged
//a default constructor (what does it do? nothing)
Month(); // done, no debugging to do
//an input function to set the month based on the month number
void getMonthByNumber(istream&); // done, debugged
//input function to set the month based on a three character input
void getMonthByName(istream&); // done, debugged
//an output function that outputs the month as an integer,
void outputMonthNumber(ostream&); // done, debugged
//an output function that outputs the month as the letters.
void outputMonthName(ostream&); // done, debugged
//a function that returns the next month as a month object

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Month nextMonth(); //
//NB: each input and output function have a single formal parameter
//for the stream

int monthNumber();

private:
int mnth;
};

//added
int Month::monthNumber()
{
return mnth;
}

Month Month::nextMonth()
{
int nextMonth = mnth + 1;
if (nextMonth == 13)
nextMonth = 1;
return Month(nextMonth);
}

Month::Month( int monthNumber)


{
mnth = monthNumber;
}

void Month::outputMonthNumber( ostream& out )


{
//cout << "The current month is "; // only for debugging
out << mnth;
}
// This implementation could profit greatly from use of an array!
void Month::outputMonthName(ostream& out)
{
// a switch is called for. We don't have one yet!
if (1 == mnth) out << "Jan";
else if (2 == mnth) out << "Feb";
else if (3 == mnth) out << "Mar";
else if (4 == mnth) out << "Apr";
else if (5 == mnth) out << "May";
else if (6 == mnth) out << "Jun ";
else if (7 == mnth) out << "Jul ";
else if (8 == mnth) out << "Aug";
else if (9 == mnth) out << "Sep";
else if (10 == mnth) out << "Oct";
else if (11 == mnth) out << "Nov";
else if (12 == mnth) out << "Dec";
}
void error(char c1, char c2, char c3)
{
cout << endl << c1 << c2 << c3 << " is not a month. Exiting\n";
exit(1);
}
void error(int n)

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

{
cout << endl << n << " is not a month number. Exiting" << endl;
exit(1);
}
void Month::getMonthByNumber(istream& in)
{
in >> mnth; // int Month::mnth;
}
// use of an array and linear search could help this implementation.
void Month::getMonthByName(istream& in)
{
// Calls error(...) which exits, if the month name is wrong.
// An enhancement would be to allow the user to fix this.
char c1, c2, c3;
in >> c1 >> c2 >> c3;
c1 = tolower(c1); //force to lower case so any case
c2 = tolower(c2); //the user enters is acceptable
c3 = tolower(c3);

if('j' == c1)
if('a' == c2)
mnth = 1; // jan
else
if ('u' == c2)
if('n' == c3)
mnth = 6; // jun
else if ('l' == c3)
mnth = 7; // jul
else error(c1, c2, c3); // ju, not n or
else error(c1, c2, c3); // j, not a or u
else
if('f' == c1)
if('e' == c2)
if('b' == c3)
mnth = 2; // feb
else error(c1, c2, c3); // fe, not b
else error(c1, c2, c3); // f, not e
else
if('m' == c1)
if('a' == c2)
if('y' == c3)
mnth = 5; // may
else
if('r' == c3)
mnth = 3; // mar
else error(c1, c2, c3); // ma not a, r
else error(c1,c2,c3); // m not a or r
else
if('a' == c1)
if('p' == c2)
if('r' == c3)
mnth = 4; // apr
else error(c1, c2, c3 ); // ap not r
else
if('u' == c2)
if('g' == c3)
mnth = 8; // aug

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

else error(c1,c2,c3); // au not g


else error(c1,c2,c3); // a not u or p
else
if('s' == c1)
if('e' == c2)
if('p' == c3)
mnth = 9; // sep
else error(c1, c2, c3); // se, not p
else error(c1, c2, c3); // s, not e
else
if('o' == c1)
if('c' == c2)
if('t' == c3)
mnth = 10; // oct
else error(c1, c2, c3); // oc, not t
else error(c1, c2, c3); // o, not c
else
if('n' == c1)
if('o' == c2)
if('v' == c3)
mnth = 11; // nov
else error(c1, c2, c3); // no, not v
else error(c1, c2, c3); // n, not o
else
if('d' == c1)
if('e' == c2)
if('c' == c3)
mnth = 12; // dec
else error(c1, c2, c3);// de, not c
else error(c1, c2, c3);// d, not e
else error(c1, c2, c3);//c1,not j,f,m,a,s,o,n,or d
}
Month::Month(char c1, char c2, char c3)
{
c1 = tolower(c1);
c2 = tolower(c2);
c3 = tolower(c3);
if('j' == c1)
if('a' == c2)
mnth=1; // jan
else if ('u' == c2)
if('n' == c3)
mnth = 6; // jun
else if('l' == c3)
mnth = 7; // jul
else error(c1, c2, c3); // ju, not n or
else error(c1, c2, c3); // j, not a or u
else if('f' == c1)
if('e' == c2)
if('b' == c3)
mnth = 2; // feb
else error(c1, c2, c3); // fe, not b
else error(c1, c2, c3); // f, not e
else
if('m' == c1)
if('a' == c2)
if('y' == c3)

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

mnth = 5; // may
else
if('r' == c3)
mnth = 3; // mar
else error(c1, c2, c3); // ma not a, r
else error(c1,c2,c3); // m not a or r
else
if('a' == c1)
if('p' == c2)
if('r' == c3)
mnth = 4; // apr
else error(c1, c2, c3 ); // ap not r
else
if('u' == c2)
if('g' == c3)
mnth = 8; // aug
else error(c1,c2,c3); // au not g
else error(c1,c2,c3); // a not u or p
else
if('s' == c1)
if('e' == c2)
if('p' == c3)
mnth = 9; // sep
else error(c1, c2, c3); // se, not p
else error(c1, c2, c3); // s, not e
else
if('o' == c1)
if('c' == c2)
if('t' == c3)
mnth = 10; // oct
else error(c1, c2, c3); // oc, not t
else error(c1, c2, c3); // o, not c
else
if('n' == c1)
if('o' == c2)
if('v' == c3)
mnth = 11; // nov
else error(c1, c2, c3); // no, not v
else error(c1, c2, c3); // n, not o
else
if('d' == c1)
if('e' == c2)
if('c' == c3)
mnth = 12; // dec
else error(c1, c2, c3); // de, not c
else error(c1, c2, c3); // d, not e
else error(c1, c2, c3);//c1 not j,f,m,a,s,o,n,or d
}
Month::Month()
{
// body deliberately empty
}

int main()
{
cout << "testing constructor Month(char, char, char)" << endl;

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Month m;
m = Month( 'j', 'a', 'n');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'f', 'e', 'b');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'm', 'a', 'r');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'a', 'p', 'r');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'm', 'a', 'y');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'j', 'u', 'n');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'j', 'u', 'l');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'a', 'u', 'g');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 's', 'e', 'p');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'o', 'c', 't');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'n', 'o', 'v');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'd', 'e', 'c');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
cout << endl << "Testing Month(int) constructor" << endl;
int i = 1;
while (i <= 12)
{
Month mm(i);
mm.outputMonthNumber( cout ); cout << " ";
mm.outputMonthName(cout); cout << endl;
i = i+1;
}
cout << endl
<< "Testing the getMonthByName and outputMonth* \n";
i = 1;
Month mm;
while (i <= 12)
{
mm.getMonthByName(cin);
mm.outputMonthNumber( cout ); cout << " ";
mm.outputMonthName(cout); cout << endl;
i = i+1;
}

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout << endl


<< "Testing getMonthByNumber and outputMonth* " << endl;
i = 1;
while (i <= 12)
{
mm.getMonthByNumber(cin);
mm.outputMonthNumber( cout ); cout << " ";
mm.outputMonthName(cout); cout << endl;
i = i+1;
}
cout << endl << "end of loops" << endl;
cout << endl << "Testing nextMonth member" << endl;
cout << "current month ";
mm.outputMonthNumber(cout); cout << endl;
cout << "next month ";
mm.nextMonth().outputMonthNumber(cout); cout << " ";
mm.nextMonth().outputMonthName(cout); cout << endl;
cout << endl << "new Month created " << endl;
Month mo(6);
cout << "current month ";
mo.outputMonthNumber(cout); cout << endl;
cout << "nextMonth ";
mo.nextMonth().outputMonthNumber(cout); cout << " ";
mo.nextMonth().outputMonthName(cout); cout << endl;
return 0;
}

/*
A partial testing run follows:
$a.out
testing constructor Month(char, char, char)
1 Jan
2 Feb
3 Mar
4 Apr
5 May
6 Jun
7 Jul
8 Aug
9 Sep
10 Oct
11 Nov
12 Dec
Testing Month(int) constructor
1 Jan

Remainder of test run omitted


*/
\

2. Redefinition of class Month


Same as #1, except state is now the 3 char variables containing the first 3 letters of month name.
Variant: Use C-string to hold month.
Variant 2: Use vector of char to hold month. This has more promise.

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

3. “Little Red Grocery Store Counter”


A good place to start is with the solution to #2 from Chapter 6.

The class counter should provide:


A default constructor. For example, Counter(9999); provides a counter that can count up
to 9999 and displays 0.
A member function, void reset() that returns count to 0
A set of functions that increment digits 1 through 4:
void incr1() //increments 1 cent digit
void incr10() //increments 10 cent digit
void incr100() //increments 100 cent ($1) digit
void incr1000() //increments 1000 cent ($10)digit
Account for carries as necessary.
A member function bool overflow(); detects overflow.
Use the class to simulate the little red grocery store money counter.
Display the 4 digits, the right most two are cents and tens of cents, the next to are dollars and
tens of dollars.
Provide keys for incrementing cents, dimes, dollars and tens of dollars.
Suggestion: asdfo: a for cents, followed by 1-9
s for dimes, followed by 1-9
d for dollars, followed by 1-9
f for tens of dollars, followed by 1-9
Followed by pressing the return key in each case.
Adding is automatic, and overflow is reported after each operation. Overflow can be requested
with the O key.
Here is a tested implementation of this simulation.

You will probably need to adjust the PAUSE_CONSTANT for your machine, otherwise the
pause can be so short as to be useless, or irritatingly long.
//Ch7prg3.cpp
//
//Simulate a counter with a button for each digit.
//Keys a for units
// s for tens, follow with digit 1-9
// d for hundreds, follow with digit 1-9
// f for thousands, follow with digit 1-9
// o for overflow report.
//
//Test thoroughly
//
//class Counter
//
// default constructor that initializes the counter to 0
// and overflowFlag to 0
// member functions:
// reset() sets count to 0 and overflowFlag to false

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

// 4 mutators each of which increment one of the 4 digits.


// (carry is accounted for)
// bool overflow() returns true if last operation resulted in
// overflow.
// 4 accessors to display each digit
// a display function to display all 4 digits
//
//
// The class keeps a non-negative integer value.
// It has an accessor that returns the count value,
// and a display member that write the current count value
// to the screen.

#include <iostream>
using namespace std;

const int PAUSE_CONSTANT = 100000000; // 1e8


void pause(); // you may need to adjust PAUSE_CONSTANT

class Counter
{
public:
Counter();

//mutators
void reset();
void incr1();
void incr10();
void incr100();
void incr1000();

//accessors
void displayUnits();
void displayTens();
void displayHundreds();
void displayThousands();

int currentCount();
void display();

bool overflow();

private:
int units;
int tens;
int hundreds;
int thousands;
bool overflowFlag;
};
int main()
{
int i;
int j; // digit to follow "asdf"
char ch;

Counter c;
int k = 100;

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

while(k-- > 0)
{
system("cls");
//system("clear");

if(c.overflow())
cout << "ALERT: OVERFLOW HAS OCCURRED. RESULTS "
<< "ARE NOT RELIABLE. Press Q to quit.\n";

cout << endl;


c.displayThousands(); c.displayHundreds();
cout << ".";
c.displayTens(); c.displayUnits();
cout << endl;
cout << "Enter a character followed by a digit 1-9:\n"
<< "Enter a for units\n"
<< " s for tens\n"
<< " d for hundreds\n"
<< " f for thousands\n"
<< " o to inquire about overflow\n"
<< "Q or q at any time to quit.\n";
cin >> ch;

//vet value of ch, other housekeeping


if(ch != 'a' && ch != 's' && ch != 'd' && ch != 'f')
{
if(ch == 'Q' || ch == 'q')
{
cout << ch << " pressed. Quitting\n";
return 0;
}

if(ch == 'o')
{ cout << "Overflow test requested\n";
if(c.overflow())
{
cout << "OVERFLOW HAS OCCURRED. RESULTS "
<< "ARE NOT RELIABLE. Press Q to quit.\n";
}
pause();
continue; //restart loop
}
cout << "Character entered not one of a, s, d, f, or o.\n";
pause();
continue; //restart loop.
}

cin >> j;
// vet value of j
if( !(0 < j && j <= 9))
{
cout << "Digit must be between 1 and 9\n";
continue;
}

switch(ch)
{

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

case 'a': for(i = 0; i < j; i++)


c.incr1();
break;
case 's': for(i = 0; i < j; i++)
c.incr10();
break;

case 'd': for(i = 0; i < j; i++)


c.incr100();
break;

case 'f': for(i = 0; i < j; i++)


c.incr1000();
break;
case 'Q': // fall through
case 'q': cout << "Quitting\n";
return 0; // quit.

default: cout << "Program should never get here\n"


<< "Fix program\n";
abort();
}
cout << "At end of switch \n";
}

return 0;
}

// Implementations

void pause()
{
cout << "Pausing for you to read . . .\n";
for(int X = 0; X < PAUSE_CONSTANT; X++)
{
X++; X--;
}
}
void Counter::displayUnits()
{
cout << units;
}
void Counter::displayTens()
{
cout << tens;
}
void Counter::displayHundreds()
{
cout << hundreds;
}
void Counter::displayThousands()
{
cout << thousands;
}

void Counter::reset()
{

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

units = tens = hundreds = thousands = 0;


overflowFlag = false;
}

void Counter::display()
{
cout << thousands << hundreds
<< tens << units ;
}

bool Counter::overflow()
{
return overflowFlag;
}

Counter::Counter():units(0), tens(0), hundreds(0),


thousands(0), overflowFlag(false)
{// body deliberately empty
}

void Counter::incr1()
{
if(units < 9)
units++;
else
{
units = 0;
if(tens < 9)
tens++;
else
{
tens = 0;
if(hundreds < 9)
hundreds++;
else
{
hundreds = 0;
if(thousands < 9)
thousands++;
else
overflowFlag = true;
}
}
}
}

void Counter::incr10()
{
if(tens < 9)
tens++;
else
{
tens = 0;
if(hundreds < 9)
hundreds++;
else
{

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

hundreds = 0;
if(thousands < 9)
thousands++;
else
overflowFlag = true;
}
}
}

void Counter::incr100()
{
if(hundreds < 9)
hundreds++;
else
{
hundreds = 0;
if(thousands < 9)
thousands++;
else
overflowFlag = true;
}
}
void Counter::incr1000()
{
if(thousands < 9)
thousands++;
else
{
thousands = 0;
overflowFlag = true;
}
}

4. Hot Dogs
You operate several hot dog stands distributed throughout town. Definite a class named
HotDogStand that has a member variable for the hot dog stand's ID number and a member
variable for how many hot dogs the stand has sold that day. Create a constructor that allows a
user of the class to initialize both values.

Also create a method named "JustSold" that increments the number of hot dogs the stand has
sold by one. The idea is that this method will be invoked each time the stand sells a hot dog so
that we can track the total number of hot dogs sold by the stand. Add another method that
returns the number of hot dogs sold.

Finally, add a static variable that tracks the total number of hotdogs sold by all hot dog stands
and a static method that returns the value in this variable.

Write a main method to test your class with at least three hot dog stands that each sell a variety
of hot dogs.

CodeMate Hint: Recall that static variables must be initialized outside of the class definition.

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

//hotdogs.cpp
//This program defines a class for tracking hot dog sales.
//
//It tracks the stand's ID number, hot dogs sold at each stand,
// and hot dogs sold at all stands.

#include <iostream>
#include <cstdlib>

using namespace std;

class HotDogStand
{
public:
HotDogStand();
HotDogStand(int newID, int newNnumSold);
int GetID();
void SetID(int newID);
void JustSold();
int GetNumSold();
static int GetTotalSold();

private:
static int totalSold;
int numSold;
int ID;
};

int HotDogStand::totalSold = 0;

// --------------------------------
// ----- ENTER YOUR CODE HERE -----
// --------------------------------

// ======================
// HotDogStand::HotDogStand
// The default constructor initializes the ID and num sold to zero.
// ======================
HotDogStand::HotDogStand()
{
numSold = 0;
ID = 0;
}

// ======================
// HotDogStand::HotDogStand
// This constructor initializes the ID and num sold.
// ======================
HotDogStand::HotDogStand(int newID, int newNumSold)
{
numSold = newNumSold;
ID = newID;
}

// ======================

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

// HotDogStand::GetID
// Returns the ID number of this stand.
// ======================
int HotDogStand::GetID()
{
return ID;
}

// ======================
// HotDogStand::SetID
// Sets the ID number of this stand.
// ======================
void HotDogStand::SetID(int newID)
{
ID = newID;
}

// ======================
// HotDogStand::JustSold
// Increments the number of hotdogs this stand
// has sold by one.
// ======================
void HotDogStand::JustSold()
{
numSold++; // increment number sold at this stand
totalSold++; // increment number sold across all stands
}

// ======================
// HotDogStand::GetNumSold
// Returns the number of hotdogs this stand has sold.
// ======================
int HotDogStand::GetNumSold()
{
return numSold;
}

// ======================
// HotDogStand::GeTotalSold
// Returns the number of hotdogs sold by all stands
// ======================
int HotDogStand::GetTotalSold()
{
return totalSold;
}

//
// --------------------------------
// --------- END USER CODE --------
// --------------------------------

// ======================
// main function
// ======================

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

int main()
{
// Test our code with three hot dog stands
HotDogStand s1(1,0),s2(2,0),s3(3,0);

// Sold at stand 1, 2
s1.JustSold();
s2.JustSold();
s1.JustSold();

cout << "Stand " << s1.GetID() << " sold " << s1.GetNumSold() << endl;
cout << "Stand " << s2.GetID() << " sold " << s2.GetNumSold() << endl;
cout << "Stand " << s3.GetID() << " sold " << s3.GetNumSold() << endl;
cout << "Total sold = " << s1.GetTotalSold() << endl;
cout << endl;

// Sold some more


s3.JustSold();
s1.JustSold();

cout << "Stand " << s1.GetID() << " sold " << s1.GetNumSold() << endl;
cout << "Stand " << s2.GetID() << " sold " << s2.GetNumSold() << endl;
cout << "Stand " << s3.GetID() << " sold " << s3.GetNumSold() << endl;
cout << "Total sold = " << s1.GetTotalSold() << endl;
cout << endl;
return 0;
}

5. Suitors
In an ancient land, the beautiful princess Eve had many suitors. She decided on the following
procedure to determine which suitor she would marry. First, all of the suitors would be lined up
one after the other and assigned numbers. The first suitor would be number 1, the second
number 2, and so on up to the last suitor, number n. Starting at the first suitor she would then
count three suitors down the line (because of the three letters in her name) and the third suitor
would be eliminated from winning her hand and removed from the line. Eve would then
continue, counting three more suitors, and eliminating every third suitor. When she reached the
end of the line she would continue counting from the beginning.

For example, if there were 6 suitors then the elimination process would proceed as follows:

123456 initial list of suitors, start counting from 1


12456 suitor 3 eliminated, continue counting from 4
1245 suitor 6 eliminated, continue counting from 1
125 suitor 4 eliminated, continue counting from 5
15 suitor 2 eliminated, continue counting from 5
1 suitor 5 eliminated, 1 is the lucky winner

Write a program that uses a vector to determine which position you should stand in to marry the
princess if there are n suitors. You will find the following method from the Vector class useful:

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

v.erase(iter);
// Removes element at position iter

For example, to use this method to erase the 4th element from the beginning of a vector variable
named theVector use:

theVector.erase(theVector.begin() + 3);

The number 3 is used since the first element in the vector is at index position 0.

CodeMate Hint: Use a vector of size n and a loop that continues to eliminate the next suitor until
the size of the vector includes only one element.

//suitors.cpp
//
//This program determines where to stand in line if you would
// like to win the hand of the princess. The princess eliminates
// every third suitor and loops back to the beginning of the line upon
// reaching the end.
//
//This program uses a vector to store the list of suitors and removes
// each one in turn.

#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;

// ======================
// main function
// ======================
int main()
{
// Variable declarations
int i;
int current;
int numSuitors;

cout << "Enter the number of suitors" << endl;


cin >> numSuitors;

vector<int> suitors(numSuitors);

for (int i=0; i<numSuitors; i++)


{
suitors[i] = i+1; // Number each suitor's position
}

// --------------------------------
// ----- ENTER YOUR CODE HERE -----
// --------------------------------

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

if (numSuitors <=0)
{
cout << "Not enough suitors." << endl;
}
else if (numSuitors == 1)
{
cout << "You would stand first in line." << endl;
}
else
{
current=0; // Current suitor the princess will examine
// Eliminate a suitor as long as there is at least one
while (suitors.size() > 1)
{
// Count three people ahead, or go two people down
// since we include the current person in the count
for (i=0; i<2; i++)
{
current++;
// If we reached the end, go back to the front
if (current == suitors.size())
{
current=0;
}
}
// Eliminate contestant current
suitors.erase(suitors.begin() + current);
// If we were at the last suitor, go to the first one
if (current == suitors.size())
{
current=0;
}
}
cout << "To win the princess, you should stand in position " <<
suitors[0] << endl;
}

// --------------------------------
// --------- END USER CODE --------
// --------------------------------
return 0;
}

6. More Pizza
This Programming Project requires you to first complete Programming Project 7 from Chapter 5,
which is an implementation of a Pizza class. Add an Order class that contains a private vector
of type Pizza. This class represents a customer’s entire order, where the order may consist of
multiple pizzas. Include appropriate functions so that a user of the Order class can add pizzas to
the order (type is deep dish, hand tossed, or pan; size is small, medium, or large; number of
pepperoni or cheese toppings). You can use constants to represent the type and size. Also write
a function that outputs everything in the order along with the total price. Write a suitable test
program that adds multiple pizzas to an order(s).

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Notes: The following solution uses the pizza.h and pizza.cpp classes from Programming Project
7 of Chapter 5.
// order.h
//
// Interface file for the Pizza ordering class.

#include "pizza.h"
#include <vector>
#include <iostream>
using namespace std;

class Order
{
public:
Order();
~Order() {};
void addPizza(Pizza p);
void outputOrder();
private:
vector<Pizza> orders;
};

// order.cpp
//
// Implementation file for the Pizza ordering class.

#include "order.h"
#include <vector>
#include <iostream>
using namespace std;

Order::Order()
{
}

// --------------------------------
// ----- ENTER YOUR CODE HERE -----
// --------------------------------

void Order::addPizza(Pizza p)
{
orders.push_back(p);
}

void Order::outputOrder()
{
double total = 0;
cout << "There are " << orders.size() <<
" pizzas in the order." << endl;
for (int i=0; i<orders.size(); i++)
{
orders[i].outputDescription();
total += orders[i].computePrice();
}

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout << "The total price is $" << total << endl;
}

// --------------------------------
// --------- END USER CODE --------
// --------------------------------

// ======================
// main function
// ======================
int main()
{
// Variable declarations
Order myOrder;
Pizza cheesy;
Pizza pepperoni;

// Make some pizzas


cheesy.setCheeseToppings(3);
cheesy.setType(HANDTOSSED);

pepperoni.setSize(LARGE);
pepperoni.setPepperoniToppings(2);
pepperoni.setType(PAN);

// Add to the order


myOrder.addPizza(cheesy);
myOrder.addPizza(pepperoni);

// Output order
myOrder.outputOrder();

cout << endl;


}

7. Money Constructor
Do Programming Project 6.8, the definition of a Money class, except create a default constructor
that sets the monetary amount to 0 dollars and 0 cents, and create a second constructor with input
parameters for the amount of the dollars and cents variables. Modify your test code to invoke the
constructors.
#include <iostream>
using namespace std;

class Money
{
public:
// Constructors
Money();
Money(int initialDollars, int initialCents);
// Functions
int getDollars();

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

int getCents();
void setDollars(int d);
void setCents(int c);
double getAmount();
private:
int dollars;
int cents;
};

Money::Money()
{
dollars = 0;
cents = 0;
}

Money::Money(int initialDollars, int initialCents) :


dollars(initialDollars), cents(initialCents)
{
}

int Money::getDollars()
{
return dollars;
}

int Money::getCents()
{
return cents;
}

void Money::setDollars(int d)
{
dollars = d;
}

void Money::setCents(int c)
{
cents = c;
}

double Money::getAmount()
{
return static_cast<double>(dollars) +
static_cast<double>(cents) / 100;
}

int main( )
{
Money m1(20, 35), m2(0, 98);

cout << m1.getDollars() << "." << m1.getCents() << endl;


cout << m1.getAmount() << endl;
cout << m2.getAmount() << endl;

cout << "Changing m1's dollars to 50" << endl;


m1.setDollars(50);
cout << m1.getAmount() << endl;

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout << "Enter a character to exit." << endl;


char wait;
cin >> wait;
return 0;
}

8. Histogram of Grades
Write a program that outputs a histogram of grades for an assignment given to a class of
students. The program should input each student’s grade as an integer and store the grade in a
vector. Grades should be entered until the user enters -1 for a grade. The program should then
scan through the vector and compute the histogram. In computing the histogram the minimum
value of a grade is 0 but your program should determine the maximum value entered by the user.
Output the histogram to the console. See Programming Project 5.7 for information on how to
compute a histogram.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
vector<int> grades;
int max = -1;
int score;
int i;

// Input grades until -1 is entered


cout << "Enter each grade and then -1 to stop." << endl;
do
{
cin >> score;
// Add to vector
if (score >= 0)
{
grades.push_back(score);
// Remember the largest value
if (score > max)
max = score;
}
} while (score != -1);

// Create histogram vector large enough to store the largest score


vector<int> histogram(max+1);
// Initialize histogram to 0
for (i=0; i<=max; i++)
{
histogram[i]=0;
}

// Loop through grades and increment histogram index


for (i=0; i<grades.size(); i++)

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

{
histogram[grades[i]]++;
}

// Output histogram
for (i=0; i<=max; i++)
{
cout << histogram[i] << " grade(s) of " << i << endl;
}
cout << endl;

cout << "Enter a character to exit." << endl;


char wait;
cin >> wait;
return 0;
}

9. POSTNET Bar Codes


The bar code on an envelope used by the US Postal Service represents a five (or more) digit zip
code using a format called POSTNET (this format is being deprecated in favor of a new system,
OneCode, in 2009). The bar code consists of long and short bars as shown below:

For this program we will represent the bar code as a string of digits. The digit 1 represents a
long bar and the digit 0 represents a short bar. Therefore, the bar code above would be
represented in our program as:

110100101000101011000010011

The first and last digits of the bar code are always 1. Removing these leave 25 digits. If these 25
digits are split into groups of five digits each then we have:

10100 10100 01010 11000 01001

Next, consider each group of five digits. There will always be exactly two 1’s in each group of
digits. Each digit stands for a number. From left to right the digits encode the values 7, 4, 2, 1,
and 0. Multiply the corresponding value with the digit and compute the sum to get the final
encoded digit for the zip code. The table below shows the encoding for 10100.
Bar Code 1 0 1 0 0
Digits
Value 7 4 2 1 0
Product of 7 0 2 0 0
Digit * Value
Zip Code Digit = 7 + 0 + 2 + 0 + 0 = 9

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Repeat this for each group of five digits and concatenate to get the complete zip code. There is
one special value. If the sum of a group of five digits is 11, then this represents the digit 0 (this
is necessary because with two digits per group it is not possible to represent zero). The zip code
for the sample bar code decodes to 99504. While the POSTNET scheme may seem
unnecessarily complex, its design allows machines to detect if errors have been made in scanning
the zip code.

Write a zip code class that encodes and decodes five digit bar codes used by the US Postal
Service on envelopes. The class should have two constructors. The first constructor should
input the zip code as an integer and the second constructor should input the zip code as a bar
code string consisting of 0’s and 1’s as described above. Although you have two ways to input
the zip code, internally the class should only store the zip code using one format (you may
choose to store it as a bar code string or as a zip code number.) The class should also have at
least two public member functions, one to return the zip code as an integer, and the other to
return the zip code in bar code format as a string. All helper functions should be declared
private. Embed your class definition in a suitable test program.

#include <iostream>
#include <string>
using namespace std;

class ZipCode
{
public:
ZipCode(int zip);
// Constructs a ZipCode from an integer zip code value
ZipCode(string code);
// Constructs a ZipCode from a string of 1's and 0's
string get_bar_code();
// Returns the zip code in bar form
int get_zip_code();
// Returns the zip code in numeric form

private:
int zip;
int parse_bar_code(string code);
// Returns an integer, parsed from the given bar code.
// If the code is not valid, this function will print
// an error message and then exit.
};

// Constructs a ZipCode from an integer zip code value


ZipCode::ZipCode(int z) : zip(z)
{
}

// Constructs a ZipCode from a string of 1's and 0's


ZipCode::ZipCode(string code)
{
zip = parse_bar_code(code);
}

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

// Returns an integer, parsed from the given bar code.


// If the code is not valid, this function will print
// an error message and then exit.
int ZipCode::parse_bar_code(string code)
{
int value = 0;

if (((code.length() - 2) % 5) != 0)
{
cout << "ERROR: '" << code << "' has invalid length " << endl
<< " (Length must be 5*n+2, where n is the number of"
<< endl
<< " digits in the zip code)" << endl;
return -1;
}
else if ((code[0] != '1') || (code[code.length() - 1] != '1'))
{
cout << "ERROR: '" << code << "' must begin and end with '1'" << endl;
return -1;
}
else
{
int digits = (code.length() - 2)/5;

// Each position 0 - 5 in each 1/0 digit sequence has


// a unique value. Putting these in an array lets us
// map a digit position to a value by doing an array
// lookup, rather than an if-else-if statement.
int values[] = { 7, 4, 2, 1, 0 };

for (int d = 0; d < digits; d++)


{
int digit = 0;
for (int i = 0; i < 5; i++)
{
char ch = code[d * 5 + i + 1];
if (ch == '1')
{
digit += values[i];
}
else if (ch != '0')
{
cout << "ERROR: '" << code
<< "' must contain only '1' and '0'" << endl;
// exit(1);
return -1;
}
}

if ((digit < 1) || (digit == 10) || (digit > 11))


{
cout << "ERROR: '" << code << "' has invalid sequence '"
<< code.substr(d * 5 + 1, 5) << "'" << endl;
// exit(1);
return -1;
}

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

if (digit == 11)
{
digit = 0;
}

value = (value * 10) + digit;


}
}
return value;
}

// Returns the zip code in numeric form


int ZipCode::get_zip_code()
{
return zip;
}

// Returns the zip code in bar form


string ZipCode::get_bar_code()
{
string code;
int z, digit, numDigits, targetDigits;

// Each digit 0-9 has a unique 5-digit bar code sequence.


// If we put these in an array, then we can simply look
// them up via an array index.
string digits[] =
{ "11000", "00011", "00101", "00110", "01001",
"01010", "01100", "10001", "10010", "10100" };

z = zip;
numDigits = 0;

// Work backwards through the zip code integer


while (z > 0)
{
// Pull off the smallest digit
digit = (z % 10);

// Then throw that digit away


z = z/10;

// Prepend the digit to the code


code = digits[digit] + code;

numDigits++;
}

// Make sure we always have at least 5 or 9 digits (zip or zip+4)


if (numDigits > 5)
{
targetDigits = 9;
}
else
{
targetDigits = 5;

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

while (numDigits < targetDigits)


{
code = digits[0] + code;
numDigits++;
}

// Put a '1' on each end


return "1" + code + "1";
}

// MAIN FUNCTION
int main()
{
ZipCode zip(99504),
zip2("100101010011100001100110001"),
zip3(12345),
zip4(67890);
int BAD_ZIP_COUNT = 5;
string bad_zips[][2] = {
{ "10010101001110000110011001", "bad length" },
{ "000101010011100001100110001", "bad start/end character" },
{ "100101010011100001100110000", "bad start/end character" },
{ "100101010011100001100110021", "bad digit" },
{ "100101010011100001100111001", "bad sequence" }
};

cout << zip.get_zip_code() << "'s bar code is '"


<< zip.get_bar_code() << "'" << endl;
cout << zip2.get_zip_code() << "'s bar code is '"
<< zip2.get_bar_code() << "'" << endl;
cout << zip3.get_zip_code() << "'s bar code is '"
<< zip3.get_bar_code() << "'" << endl;
cout << zip4.get_zip_code() << "'s bar code is '"
<< zip4.get_bar_code() << "'" << endl;

cout << endl;

// Test a range of values by first constructing a zip code with


// an integer, then retrieving the bar code and using that to
// construct another ZipCode.
int zip_int = 0;
for (int i = 0; i < 25; i++)
{
// Make an aribrary 5-digit zip code integer, and use it
// to construct a ZipCode
int five_digit_zip = (zip_int * zip_int) % 100000;
ZipCode z1(five_digit_zip);

// Construct a second ZipCode from the first's bar code


string z1_code = z1.get_bar_code();
ZipCode z2(z1_code);

cout.width(3);
cout << (i + 1) << ": ";

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout.width(5);
cout << z2.get_zip_code() << " has code '"
<< z1_code << "'";

if ((z1_code == z2.get_bar_code()) &&


(z1.get_zip_code() == z2.get_zip_code()) &&
(z2.get_zip_code() == five_digit_zip))
{
cout << " [OK]" << endl;
}
else
{
cout << " [ERR]" << endl;
}

// Increment the test value arbitrarily


zip_int += (233 + zip_int % 7);
}

cout << endl;

// Test some error conditions. This test assumes that


// ZipCode will simply set its value to a flag that indicates
// an error, and will not exit the program.
for (int i = 0; i < BAD_ZIP_COUNT; i++)
{
cout << "Testing: " << bad_zips[i][1] << endl;
ZipCode test(bad_zips[i][0]);
cout << endl;
}

cout << "Enter a character to quit." << endl;


char c;
cin >> c;
return 0;
}

10. Static variable in Box Of Produce


First, complete Programming Project 6.12. Modify the main function with a loop so that an
arbitrary number of BoxOfProduce objects are created and substitutions are allowed for each box.
Add a menu so the user can decide when to stop creating boxes.

You would like to throw in a free recipe flyer for salsa verde if the box contains tomatillos.
However, there are only 5 recipe flyers. Add a static member variable to the BoxOfProduce class
that counts the number of recipe flyers remaining and initialize it to 5. Also add a member
variable that indicates whether or not the box contains a recipe flyer and modify the output
function to also print "salsa verde recipe" if the box contains a recipe flyer. Finally, add logic
inside the class so that if the box contains at least one order of tomatillos then it automatically gets
a recipe flyer until all of the recipe flyers are gone. Note that a box should only get one recipe flyer
even if there are multiple orders of tomatillos.

Test your class by creating boxes with tomatillos from your menu until all of the flyers are gone.

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;

// Max number of bundles in a box


const int MAX_BUNDLES = 100;

class BoxOfProduce
{
private:
int numBundles;
string bundle[MAX_BUNDLES];
bool hasSalsaFlyer;
void tomatilloCheck();
static int numSalsaFlyers;
public:
BoxOfProduce();
void initialize();
void addBundle(string b);
string getBundle(int index);
void setBundle(string b, int index);
string boxContents();
};

// Initialize the static variable


int BoxOfProduce::numSalsaFlyers = 5;

BoxOfProduce::BoxOfProduce()
{
initialize();
}

void BoxOfProduce::initialize()
{
numBundles = 0;
hasSalsaFlyer = false;
}

// If the bundle contains tomatillos and we have


// flyers left, then set the hasFlyer variable
// and subtract one from the number of flyers left.
// Once we have added a flyer to a box we don't
// remove it.
void BoxOfProduce::tomatilloCheck()
{
// If box has a flyer then exit
if (hasSalsaFlyer)
return;
// If no flyers left, then exit
if (numSalsaFlyers == 0)
return;

// Check if there are any tomatillos

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

for (int i = 0; i < numBundles; i++)


if (bundle[i] == "Tomatillo")
{
// Add salsa flyer
hasSalsaFlyer = true;
numSalsaFlyers--;
}
}

void BoxOfProduce::addBundle(string b)
{
if (numBundles < MAX_BUNDLES)
{
bundle[numBundles] = b;
numBundles++;
}
// Check if we should add a salsa flyer
tomatilloCheck();
}

string BoxOfProduce::getBundle(int index)


{
if ((index >=0) && (index < MAX_BUNDLES))
return bundle[index];
else
return "";
}

void BoxOfProduce::setBundle(string b, int index)


{
if ((index >=0) && (index < MAX_BUNDLES))
bundle[index] = b;
// Check if we should add a salsa flyer
tomatilloCheck();
}

string BoxOfProduce::boxContents()
{
string s = "The box contains: ";
for (int i = 0; i < numBundles; i++)
s = s + " (" + char('0'+i+1) + ")" + bundle[i];
if (hasSalsaFlyer)
s = s + ". Bonus - Salsa Verde Recipe Flyer";
return s;
}

int main()
{
char addMoreBoxes;
do
{
// Create a Box
BoxOfProduce box;
box.initialize();

// Initialize the random number generator

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

srand(time(NULL));
// Pick three random numbers from 0 to 4 for the 5 possible food
choices
int num1, num2, num3;
num1 = rand() % 5;
num2 = rand() % 5;
num3 = rand() % 5;

int lineRead = 0;
ifstream inputStream;
inputStream.open("produce.txt");

string food;
while (inputStream >> food)
{
if (lineRead == num1)
box.addBundle(food);
if (lineRead == num2)
box.addBundle(food);
if (lineRead == num3)
box.addBundle(food);
lineRead++;
}
inputStream.close();

// Show the box contents to the user and allow substitutions


char selection = ' ';
do
{
cout << box.boxContents() << endl;
cout << "Enter 'a' to add a new bundle." << endl;
cout << "Enter 'c' to change a bundle." << endl;
cout << "Enter 'q' to quit." << endl;
cin >> selection;
if (selection == 'a')
{
cout << "Enter item to add." << endl;
string item;
cin >> item;
box.addBundle(item);
}
else if (selection == 'c')
{
cout << "Enter index of item to change." << endl;
int i;
cin >> i;
cout << "Enter item to substitute." << endl;
string item;
cin >> item;
box.setBundle(item, i-1); // Index is 0 based so sub 1
}
} while (selection != 'q');
cout << "Final Contents:" << endl;
cout << box.boxContents() << endl;

cout << endl;


cout << "Add another box? (y/n)" << endl;

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cin >> addMoreBoxes;


} while (addMoreBoxes == 'y');
return 0;
}

Copyright © 2012 Pearson Education Addison-Wesley. All rights reserved.


Another random document with
no related content on Scribd:
of revelation. But again we catch ourselves sermonizing: to the
diagram.
Fossils from the London Clay.

1. Tellina crassa.
2. Chama squamosa.
3. Turritella imbricataria.
4. Fusus asper.
5. Pleurotoma colon.
6. Murex tubifer.
7. Aporhais pes-pelicani.
8. Voluta luctator (or luctatrix).
9. Trochus monolifer: the necklace trochus.
10. Venericardia cor-avium.
11. Fusus bulbiformis: the bulb fusus.
These fossils we obtained from the neighbourhood of
Christchurch; and as these sheets were being written, we received
from Dr. Mantell’s “Geological Excursions in the Isle of Wight,” the
following appropriate description of them: “The numerous marine
fossil shells which are obtained from this part of the coast of
Hampshire, are generally known as Hordwell fossils; but it is
scarcely necessary to remark, that they almost entirely belong to the
London clay strata, and are procured from Barton cliffs. These fossils
are most conveniently obtained from the low cliff near Beacon
Bunny, and occur in greatest abundance in the upper part of the dark
green sandy clay. There are generally blocks of the indurated
portions of the strata on the beach, from which fossils may be
extracted. A collection of Hordwell fossils, consisting of the teeth of
several species of sharks and rays, bones of turtles, and a great
variety of shells, may be purchased at a reasonable price of Jane
Webber, dealer in fossils, Barton cliff, near Christchurch.”—(P. 124.)
Before leaving the Eocene, or rather the London clay of the
Eocene, we will give a drawing of a fossil in our possession. The
drawing opposite represents a piece of fossil wood, pierced through
and through by Teredinæ, a boring mollusk allied to the Teredo,
which still proves so destructive to our vessels. Although the wood is
converted into a stony mass, and in some parts covered by calcareous
matter, the same as is found in the septaria, so common in these
beds, to which we shall presently direct attention, still the grain and
woody texture are most distinct. This wood was once probably
floating down what we now call the Thames, when these piercing,
boring mollusks seized hold upon it, penetrated its soft texture, and
lived, moved, and had their being down at the bottom of the river in
their self-constructed chambers. Time rolled on, and the log of wood
is floated upon the shore, and there it lies to harden and to dry; again
the log is drifted away, and, buried in some soft bed of clay, is
preserved from rotting. In process of time it again sees the light; but
now saturated by argillaceous material, and when hardened by the
sun, becomes the petrifaction such as we see it.
WOOD PERFORATED RY TEREDINA PERSONATA, LONDON
CLAY.

Here let us refer to the septaria, of which we have just spoken; two
specimens lie before us, which we will briefly describe. In one (1) the
clay is in distinct lozenge-shaped masses of a blue colour, while veins
of calcareous spar or crystallized carbonate of lime surround these,
which are capable of a beautiful marble-like polish; in the other (2)
the clay is of the same colour, only in larger proportions, and the
spar is of a deep brown colour, while here and there portions of iron
pyrites may be seen; they become beautiful ornaments in a room
when cut and polished. It should be added, that the septaria are not
without their economic uses, being extensively used as cement after
being stamped and burnt.
SEPTARIA

Here we may leave this brief sketch of the Eocene, or lowest beds
of the Tertiary. A new creation has been introduced to our view; and
although we still wait for the coming of man—the lord and
interpreter of all—the contemplation of these successive acts and
centres of creation fills our minds with renewed admiration and
reverence of Him for whom, and by whom, and to whom are all
things. Thus “even Geology, while it has exhumed and revivified long
buried worlds, peopled with strange forms in which we can feel little
more than a speculative interest, and compared with which the most
savage dweller in the wilderness of the modern period—jackal,
hyæna, or obscene vulture—is as a cherished pet and bosom friend,
has made for us new bonds of connexion between remote regions of
the earth as it is, on account of which we owe it a proportionate share
of gratitude.”[117]
No. II.—The Miocene.
We shall briefly pass over this period. At Bordeaux, Piedmont, and
in Lisbon, this formation is seen; as well as in various other parts of
the Continent of Europe. The supposition of Geology is, that during
this period “whole regions of volcanoes burst forth, whose lofty but
now tranquil cones can be seen in Catalonia, in Spain, in France,
Switzerland, Asia, and in America. The Alps, the Carpathian
Mountains, and other lofty ranges were at this period partially
upheaved. The researches of Sir Robert Murchison have established
this fact, by his finding deep beds of limestone, characteristic of the
Tertiary period, on the summit of one of the loftiest of the Alps, fully
ten thousand feet above the level of the sea.”
No. III.—The Pliocene Period.
This term has already been explained. We shall only detain the
reader by a few words respecting the organic remains that
characterize this formation. In England it is confined to the eastern
part of the county of Suffolk, where it is called “Crag.” This is a mere
provincial name, given particularly to those masses of shelly sand
which are used to fertilize lands deficient in calcareous matter. The
geological name given to this strata is the “Red or Coralline Crag;”
and it is so called on account of the deep ferruginous colour its fossils
have through extensive oxidization of iron. We give drawings of the
fossils of the Red Crag, obtained from the neighbourhood of Ipswich.
FOSSILS FROM THE RED
CRAG, NEAR IPSWICH.

1. Venericardia senilis.
2. Turritella.
3. Patella æqualis.
4. Cyprea.
5. Paludina lenta.
6. Pectunculus variabilis.
7. Murex.
8. Fusus contrarius.
9. Buccinum elongata.
10. Venericardia scalaris.
11. Voluta lamberti.
12. Fusus asper.
13. Pectunculus pilosus.
But these are not the only fossils of this period; it is here we meet,
and that for the first time, with the highest form of animal life with
which the researches of geology have made us acquainted. We have
traced life in various forms in the different rocks that have passed
under our rapid survey, and in all we have seen a wondrous and most
orderly gradation. We began with the coral zoophytes, and from
them proceeded to the mollusks and crustacea of the hypogene
rocks; ascending, we discovered “fish with glittering scales,”
associated with the crinoids and cryptogamous plants of the
secondary series of rocks; and then we arrive where we are now,
among the true dicotyledonous and exogenous plants and trees, with
the strange birds and gigantic quadrupeds of the tertiary period. But
the student must not imagine that even the fossils of this epoch bring
him up to the modern era, or the reign of man; for even in the
tertiary system numberless species lived and flourished, which in
their turn became extinct, to be succeeded by others long before
man, the chief of animals and something more, made his
appearance, to hold dominion over these manifold productions of
creative skill and power. But amidst these creations,
“God was everywhere, the God who framed
Mankind to be one mighty human family,
Himself their Father, and the world their home.”

It would be altogether beside the purpose of this preliminary


treatise to enter into any details respecting the animals that have
been found in such abundance in the Norwich Crag, that it has been
called the “Mammaliferous Crag.” Those who desire full and deeply
interesting information on this question should consult Owen’s noble
work, entitled “British Fossil Mammals and Birds,” where, under the
respective divisions of Eocene, Miocene, and Pliocene, he will see a
complete chart of our riches in the possessions of a past creation. For
the discovery of the Siberian Mammoth so often quoted, we shall
refer to the same work, page 217, &c.; from which we shall only quote
one brief extract, illustrative of the abundance of these remains in
our own coasts in the ages past.
“Mr. Woodward, in his ‘Geology of Norfolk,’ supposes that
upwards of two thousand grinders of the mammoth have been
dredged up by the fishermen of the little village of Happisburgh in
the space of thirteen years. The oyster-bed was discovered here in
1820; and during the first twelve months hundreds of the molar
teeth of mammoths were landed in strange association with the
edible mollusca. Great quantities of the bones and tusks of the
mammoth are, doubtless, annually destroyed by the action of the
waves of the sea. Remains of the mammoth are hardly less numerous
in Suffolk, especially in the pleistocene beds along the coast, and at
Stutton;—they become more rare in the fluvio-marine crag at
Southwold and Thorp. The village of Walton, near Harwich, is
famous for the abundance of these fossils, which lie along the base of
the sea-cliffs, mixed with bones of species of horse, ox, and deer.”[118]

SKELETON OF THE MEGATHERIUM CUVIERI


(AMERICANUM).

All the animals of this period are called theroid animals: from
therion, a wild beast; and looking at the skeletons as they have been
arranged from the few existing fossils, or from nearly complete
materials—a matter not of guess-work, but of the most rigid
application of the principles of comparative anatomy—we stand
astounded at the prodigious sizes of these mammoths of the tertiary
era. There is the deinotherium, or fierce wild beast; the
palæotherium, or ancient wild beast; the anoplotherium, or
unarmed wild beast, and others. We give above a drawing of the well-
known megatherium, or great wild beast, to be seen in the British
Museum, and add the following from Mantell’s Guide to the Fossils
of the British Museum:—“This stupendous extinct animal of the sloth
tribe was first made known to European naturalists by a skeleton,
almost entire, dug up in 1789, on the banks of a river in South
America, named the Luxon, about three miles south-east of Buenos
Ayres. The specimen was sent to Madrid, and fixed up in the
Museum, in the form represented in numerous works on natural
history. A second skeleton was exhumed at Lima, in 1795; and of late
years Sir Woodbine Parish, Mr. Darwin, and other naturalists have
sent bones of the megatherium, and other allied genera, to England.
The model of the megatherium has been constructed with great care
from the original bones, in the Wall-cases 9, 10, and in the Hunterian
Museum. The attitude given to the skeleton, with the right arm
clasping a tree, is, of course, hypothetical; and the position of the
hinder toes and feet does not appear to be natural. Altogether,
however, the construction is highly satisfactory; and a better idea of
the colossal proportions of the original is conveyed by this model,
than could otherwise be obtained.”[119]

SKELETON OF THE MASTODON OHIOTICUS, FROM NORTH


AMERICA.
(Height, 9½ feet; length, 20 feet.)

We give below a drawing of the “Mastodon Ohioticus;” for the


following account of which we are indebted to the same source. It
will be found in Room 6, figure 1.—“This fine skeleton was purchased
by the trustees of the British Museum of Albert Koch, a well-known
collector of fossil remains; who had exhibited, in the Egyptian Hall,
Piccadilly, under the name of the Missourium, or Leviathan of the
Missouri, an enormous osteological monster, constructed of the
bones of this skeleton, together with many belonging to other
individuals—the tusks being fixed in their sockets so as to curve
outwards on each side of the head. From this heterogeneous
assemblage of bones, those belonging to the same animal were
selected, and are articulated in their natural juxtaposition.”[120]

FOSSIL HUMAN SKELETON, FROM GUADALOUPE.


(The original 4 feet 2 inches long, by 2
feet wide.)
PLAN OF THE CLIFF AT GAUDALOUPE.

In Wall-case D of the British Museum, may be seen a fossil


skeleton of a human being, brought from the island of Guadaloupe,
the consideration of which must for ever remove any idea that may
exist about man being contemporaneous with the theroidal
mammals of which we have been speaking.[121] Professor Whewell has
remarked that the “gradation in form between man and other
animals is but a slight and unimportant feature in contemplating the
great subject of the origin of the human race. Even if we had not
revelation to guide us, it would be most unphilosophical to attempt
to trace back the history of man, without taking into account the
most remarkable facts in his nature: the facts of civilization, arts,
government, speech—his traditions—his internal wants—his
intellectual, moral, and religious constitution. If we will attempt a
retrospect, we must look at all these things as evidence of the origin
and end of man’s being; and we do thus comprehend, in one view,
the whole of the argument—it is impossible for us to arrive at an
origin homogeneous with the present order of things. On this
subject, the geologist may, therefore, be well content to close the
volume of the earth’s physical history, and open that divine record
which has for its subject the moral and religious nature of man.”
“Mysterious framework of bone, locked up in the solid marble,—
unwonted prisoner of the rock! an irresistible voice shall yet call thee
out of thy stony matrix. The other organisms, thy partners in the
show, are incarcerated in the lime for ever,—thou but for a term.
How strangely has the destiny of the race to which thou belongest re-
stamped with new meanings the old phenomena of creation!... When
thou wert living, prisoner of the marble, haply as an Indian wife and
mother, ages ere the keel of Columbus had disturbed the waves of the
Atlantic, the high standing of thy species had imparted new
meanings to death and the rainbow. The prismatic arch had become
the bow of the covenant, and death a great sign of the unbending
justice and purity of the Creator, and of the aberration and fall of the
living soul, formed in the Creator’s own image,—reasoning,
responsible man.”[122]

FINIS:—THE GEOLOGIST’S DREAM.

ALARM, BUT NO DANGER.


CHAPTER XIII.
SCRIPTURE AND GEOLOGY; OR, APPARENT
CONTRADICTIONS RECONCILED.

“By Him were all things created, that are in heaven, and that are in earth,
visible and invisible, whether they be thrones, or dominions, or
principalities, or powers; all things were created by Him, and for Him;
and He is before all things, and by Him all things consist.”—Paul.

We have in the course of the previous volume alluded to certain


discrepancies, supposed to exist between the statements of Scripture,
and the teachings of Geology. We have more than once intimated our
intention of discussing at some length these questions, that have so
long been tabooed by truly religious people, and often needlessly
exaggerated by those who have possessed a “microscopic eye,” in the
discovery of the weak points of Christian faith or opinion. Dropping
the convenient and euphonious form of egotism, which allows
sovereigns and authors to adopt the plural, we shall crave to stand
before our readers in our personal and singular, rather than in our
impersonal and plural, form of speech.

To the reader let me first say, that while I do not wish to appear
before him as an advocate, as if I held a brief or had a retaining fee
on behalf of Moses, I nevertheless feel rather keenly that the
“reverend” put before my name may give something like this aspect
to all my remarks. It may be thought, and that honestly enough, that
because mine is the clerical profession, I am bound, per fas aut
nefas, to contend for the authority of Scripture. It may be thought—
in fact, it is daily alleged against us—that the particular “stand-point”
we occupy is an unfair one, inasmuch as a preacher is bound to “stick
to the Bible;” and indeed that he always comes to it with certain à
priori conclusions, that to a great extent invalidate his reasonings,
and destroy the morality of his arguments.
Possibly there may be more truth in this than any of us dream of:
fas est ab hoste doceri. I therefore make no professions of honesty,
and appeal to no one’s feelings; let us go and look at the Bible, and at
the earth’s crust, and be guided by our independent researches.
Should this happen to be read by any one whose mind is out of joint
with Scripture; who no longer reposes with satisfaction on the old
book of his childhood and his youth; who has begun to fear,—
perhaps to think that it is only a collection of “cunningly devised”
fables; and who is on the verge of giving up Christianity and all “that
sort of thing;” to such an one I shall speak, supposing him to be as
honest in his doubts as I am in my convictions. I cannot deal with
man as if he had no right to doubt; I have never yet “pooh-poohed”
any one’s unbelief; but I have always striven to regard all doubts
expressed in courteous phrase, as the result of investigation, even
though it may be partial, as the fruit of study, although it may have
been misguided, and as the painful conclusions of a thinking mind,
and not cherished for the sake of “having a fling” at moral truth or a
righteous life, or at the mothers and sisters whose life “remote from
public haunt” has saved them from ever doubting the truth of
revelation.
Doubting and scorning are very opposite phases of mind: we here
address the doubter; with the scorner we have nothing to do; if
ridicule is his substitute for argument, by all means let him enjoy it;
and if calling names is his substitute for patient investigation, let
him enjoy that pastime also—hard words break no bones; but for the
doubter, for the man who has his honest difficulties, and finds large
stumbling-blocks in the path of unresisting acquiescence in
household faiths, for such an one I have much to say in this chapter,
if he will read it,—to him I stretch forth my hand in cordial greeting,
and invite him to examine evidence, and consider facts; and then,
whatever may be the result, whether I shake his doubts or he shake
my faith, we shall at least have acted a manly and a straightforward
part. At any rate, we ought ever to meet as friends, and to be candid
and forbearing, as men liable to err through manifold besetments
and biasses.
Having thus thrown myself upon my reader’s candour, by a clear
avowal of the spirit in which such controversies ought to be
conducted, let us together proceed to the purpose of this chapter.
Between Geology and Scripture interpretation there are apparent
and great contradictions—that all admit: on the very threshold of our
future remarks, let us allow most readily that between the usually
recognised interpretations of Scripture and the well-ascertained facts
of Geological science, there are most appalling contradictions; and
the questions arising thence are very important, both in a scientific
and in a theological point of view. Is there any method of
reconciliation, by which the harmony of the facts of science with the
statements of the Bible can be shown? Where is the real solution to
be found? Are we mistaken in our interpretations, or are we
mistaken in our discoveries? Have we to begin religion again de
novo, or may the Bible and the Book of Nature remain just as we
have been accustomed to regard them; both as equally inspired
books of God, waiting only the service and worship of man, their
priest and interpreter?
These are questions surely of no common importance. Neither the
Christian nor the doubter act a consistent part in ignoring them.
Should the Christian say, “I want no teachings of science: I want no
learned phrases and learned researches to assist me in
understanding my Bible: for aught I care, all the ‘ologies’ in the world
may perish as carnal literature: I know the Book is true, and decline
any controversy with the mere intellectual disputant;” and if the
Christian should go on to add, as probably he would in such a state of
mind, and as, alas! too many have done to the lasting disgust and
alienation of the thoughtful and intelligent: “These are the doubts of
a ‘philosophy falsely so called:’ science has nothing to do with
Revelation: they have separate paths to pursue; let them each go
their own way: and should there come a collision between the two,
we are prepared to give up all science once and for ever, whatever it
may teach, rather than have our views upon Revelation disturbed:”—
now, if the Christian talks like that, he is acting a most unwise part.
He is doing in his limited sphere of influence what the Prussian
Government intended to have done when Strauss’ “Life of Christ”
appeared. It was the heaviest blow that unbelief had ever struck
against Christianity, and the Government of Prussia with several
theological professors were disposed to prosecute its author, and
forbid the sale of the book. But the great Neander deprecated this
course, as calculated to give the work a spurious celebrity, and as
wearing the aspect of a confession that the book was unanswerable.
He advised that it should be met, not by authority, but by argument,
believing that the truth had nothing to fear in such a conflict. His
counsel prevailed, and the event has shown that he was right.
If, on the other hand, the doubter should say, “The intelligence of
the day has outgrown our household faiths; men are no longer to be
held in trammels of weakness and superstition, or to be dragooned
into Religion;—the old story about the Bible, why, you know we can’t
receive that, and look upon those compilations that pass by that
name as divinely inspired Books; we have long since been compelled
to abandon the thought that Christianity has any historic basis, or
that its Books have any claim upon the reverence or faith of the
nineteenth century, as of supernatural origin.”
To such an one I should say, that this begging of the question, this
petitio principii, is no argument; these are statements that require
every one of them a thorough demonstration before they are
admitted; you deny the Christian one single postulate: you deny him
the liberty of taking anything for granted; and then begin yourself
with demanding his assent unquestioned to so large a postulate as
your very first utterance involves, “that the intelligence of the age has
outgrown our household faiths.” Before you proceed you must prove
that; and we must know what is meant by those terms, before we can
stand upon common ground, and hold anything like argument upon
these debated points.
From such general observations let us come to the precise objects
before us: Geology and Scripture are supposed to be at variance
specially on three points. The age of the earth: the introduction of
death: and the Noachian Deluge. These apparent contradictions are
the most prominent difficulties, and cause the most startling doubts
among those who imagine Science to be antagonistic to Christian
revelation. I propose to devote a little attention to each of these
questions, while I endeavour honestly to show how, in my opinion,
apparent contradictions may be reconciled. The questions are these,
to state them in a popular form: 1. Is the world more than 6,000
years old? and if it is, how are the statements of Scripture and
Geology to be reconciled? 2. Was death introduced into the world
before the fall of man? and if it was, how are the truths of Scripture
on this question to be explained? and, 3. What was the character of
the Noachian Deluge? was it partial or universal? and what are the
apparent discrepancies in this case, between science and the Bible?
Perhaps before I proceed a step further I ought to add that, in my
belief, the age of the earth, so far as its material fabric, i.e. its crust, is
concerned, dates back to a period so remote, and so incalculable, that
the epoch of the earth’s creation is wholly unascertained and
unascertainable by our human arithmetic; whether this is
contradicted in the Scripture, is another question.
With regard to the introduction of death, I believe that death upon
a most extensive scale prevailed upon the earth, and in the waters
that are under the earth, ages, yea countless ages, before the creation
of man—before the sin of any human being had been witnessed; that
is what Geology teaches most indisputably: whether the Scriptures
contradict this statement, is another question.
With regard to the Noachian Deluge, I believe that it was quite
partial in its character, and very temporary in its duration; that it
destroyed only those animals that were found in those parts of the
earth then inhabited by man; and that it has not left one single shell,
or fossil, or any drift or other remains that can be traced to its action.
Whether the Scriptures teach any other doctrine, is another question.
By this time the ground between us is narrowed, and I may
probably anticipate that I shall have objections to answer, or
misapprehensions to remove, quite as much on the part of those who
devoutly believe, as on the part of those who honestly doubt the
Christian Scriptures.
First then,
I. How old is the world? How many years is it since it was called
into being, as one of the planets? How many centuries have elapsed
since its first particle of matter was created?
The answer comes from a thousand voices, “How old? why, 6,000
years, and no more, or closely thereabouts! Every child knows that;—
talk about the age of the world at this time of day, when the Bible
clearly reveals it!”
Now I ask, Where does the Bible reveal it? Where is the chapter
and the verse in which its age is recorded? I have read my Bible
somewhat, and feel a deepening reverence for it, but as yet I have
never read that. I see the age of man recorded there; I see the
revelation that says the human species is not much more than 6,000
years old; and geology says this testimony is true, for no remains of
man have been found even in the tertiary system, the latest of all the
geological formations. “The Bible, the writings of Moses,” says Dr.
Chalmers, “do not fix the antiquity of the globe; if they fix any thing
at all, it is only the antiquity of the species.”
It may be said that the Bible does not dogmatically teach this
doctrine of the antiquity of the globe; and we reply, Very true; but
how have we got the idea that the Bible was to teach us all physical
science, as well as theology. Turretin went to the Bible for
Astronomy: Turretin was a distinguished professor of theology in his
day, and has left behind him large proofs of scholarship and piety.
Well, Turretin went to the Bible, determined to find his system of
astronomy in it; and of course he found it. “The sun,” he says, “is not
fixed in the heavens, but moves through the heavens, and is said in
Scripture to rise and to set, and by a miracle to have stood still in the
time of Joshua; if the sun did not move, how could birds, which
often fly off through an hour’s circuit, be able to return to their
nests, for in the mean time the earth would move 450 miles?” And if
it be said in reply, that Scripture speaks according to common
opinion, then says Turretin, “We answer, that the Spirit of God best
understands natural things, and is not the author of any error.”
We smile at such “ecclesiastical drum” noise now, and we can well
afford to do so: but when people go to the Bible, determined to find
there, not a central truth, but the truths of physics, in every
department of natural science, are we to be surprised that they come
away disappointed and angry? As Michaelis says, (quoted by Dr.
Harris, in his “Man Primeval,” p. 12,) “Should a stickler for
Copernicus and the true system of the world carry his zeal so far as to
say, that the city of Berlin sets at such an hour, instead of making
use of the common expression, that the sun sets at Berlin at such an
hour, he speaks the truth, to be sure, but his manner of speaking it is
pedantry.”
Now, this is just the way to make thoughtful men unbelievers: and
we will not adopt that plan, because it is not honest, neither is it

You might also like