- •Introduction
- •Saving Time with This Book
- •Conventions Used in This Book
- •Part II: Working with the Pre-Processor
- •Part III: Types
- •Part IV: Classes
- •Part V: Arrays and Templates
- •Part VI: Input and Output
- •Part VII: Using the Built-in Functionality
- •Part VIII: Utilities
- •Part IX: Debugging C++ Applications
- •Part X: The Scary (or Fun!) Stuff
- •Icons Used in This Book
- •Creating and Implementing an Encapsulated Class
- •Creating a Mailing-List Application
- •Testing the Mailing-List Application
- •Customizing a Class with Polymorphism
- •Testing the Virtual Function Code
- •Why Do the Destructors Work?
- •Delayed Construction
- •The cDate Class
- •Testing the cDate Class
- •Creating the Header File
- •Testing the Header File
- •The Assert Problem
- •Fixing the Assert Problem
- •Using the const Construct
- •Identifying the Errors
- •Fixing the Errors
- •Fixing What Went Wrong with the Macro
- •Using Macros Appropriately
- •Using the sizeof Function
- •Evaluating the Results
- •Using sizeof with Pointers
- •Implementing the Range Class
- •Testing the Range Class
- •Creating the Matrix Class
- •Matrix Operations
- •Multiplying a Matrix by a Scalar Value
- •Multiplying a Matrix by Scalar Values, Take 2
- •Testing the Matrix Class
- •Implementing the Enumeration Class
- •Testing the Enumeration Class
- •Implementing Structures
- •Interpreting the Output
- •Defining Constants
- •Testing the Constant Application
- •Using the const Keyword
- •Illustrating Scope
- •Interpreting the Output
- •Using Casts
- •Addressing the Compiler Problems
- •Testing the Changes
- •Implementing Member-Function Pointers
- •Updating Your Code with Member-Function Pointers
- •Testing the Member Pointer Code
- •Customizing Functions We Wrote Ourselves
- •Testing the Default Code
- •Fixing the Problem
- •Testing the Complete Class
- •Implementing Virtual Inheritance
- •Correcting the Code
- •Rules for Creating Overloaded Operators
- •Using Conversion Operators
- •Using Overloaded Operators
- •Testing the MyString Class
- •Rules for Implementing new and delete Handlers
- •Overloading new and delete Handlers
- •Testing the Memory Allocation Tracker
- •Implementing Properties
- •Testing the Property Class
- •Implementing Data Validation with Classes
- •Testing Your SSN Validator Class
- •Creating the Date Class
- •Testing the Date Class
- •Some Final Thoughts on the Date Class
- •Creating a Factory Class
- •Testing the Factory
- •Enhancing the Manager Class
- •Implementing Mix-In Classes
- •Testing the Template Classes
- •Implementing Function Templates
- •Creating Method Templates
- •Using the Vector Class
- •Creating the String Array Class
- •Working with Vector Algorithms
- •Creating an Array of Heterogeneous Objects
- •Creating the Column Class
- •Creating the Row Class
- •Creating the Spreadsheet Class
- •Testing Your Spreadsheet
- •Working with Streams
- •Testing the File-Reading Code
- •Creating the Test File
- •Reading Delimited Files
- •Testing the Code
- •Creating the XML Writer
- •Testing the XML Writer
- •Creating the Configuration-File Class
- •Setting Up Your Test File
- •Building the Language Files
- •Creating an Input Text File
- •Reading the International File
- •Testing the String Reader
- •Creating a Translator Class
- •Testing the Translator Class
- •Creating a Virtual File Class
- •Testing the Virtual File Class
- •Using the auto_ptr Class
- •Creating a Memory Safe Buffer Class
- •Throwing and Logging Exceptions
- •Dealing with Unhandled Exceptions
- •Re-throwing Exceptions
- •Creating the Wildcard Matching Class
- •Testing the Wildcard Matching Class
- •Creating the URL Codec Class
- •Testing the URL Codec Class
- •Testing the Rot13 Algorithm
- •Testing the XOR Algorithm
- •Implementing the transform Function to Convert Strings
- •Testing the String Conversions
- •Implementing the Serialization Interface
- •Creating the Buffer Class
- •Testing the Buffer Class
- •Creating the Multiple-Search-Path Class
- •Testing the Multiple-Search-Path Class
- •Testing the Flow Trace System
- •The assert Macro
- •Logging
- •Testing the Logger Class
- •Design by Contract
- •Adding Logging to the Application
- •Making Functions Inline
- •Avoiding Temporary Objects
- •Passing Objects by Reference
- •Choosing Initialization Instead of Assignment
- •Learning How Code Operates
- •Testing the Properties Class
- •Creating the Locking Mechanism
- •Testing the Locking Mechanism
- •Testing the File-Guardian Class
- •Implementing the Complex Class
- •Creating the Conversion Code
- •Testing the Conversion Code
- •A Sample Program
- •Componentizing
- •Restructuring
- •Specialization
- •Index
Testing Your Spreadsheet 221
provides access to the individual rows in the sheet, without any knowledge of how the columns are stored in each row.
2. Save the source file in the source-code editor and close the editor application.
Testing Your Spreadsheet
To see that the code is really working, implement a test driver for the code. The following steps show you how:
1. In the code editor of your choice, reopen the source file for the code that you just created.
In this example, the file is named ch39.cpp, although you can use whatever you choose.
2. Append the code from Listing 39-4 to the end of your file.
Better yet, copy the code from the source file on this book’s companion Web site.
LISTING 39-4: THE SPREADSHEET TEST DRIVER
int main(int argc, char **argv)
{
Spreadsheet s1(“Sheet1”, 10, 10 );
// Initialize the spreadsheet.
for ( int i=0; i<s1.NumRows(); ++i ) for ( int j=0; j<s1.NumColumns();
++j )
{
s1[i][j] = “*”; s1[i][j].setFormat(“%6s”);
} |
|
|
// Set some values. |
|
5 |
s1[5][4] = “Hello”; |
|
|
s1[0][0] = “Begin”; |
|
//Display it so that the user can see
it.
s1.Print();
//Get a slice of the spreadsheet. Spreadsheet s2 = s1(0,0,3,3); s2.setName(“Sheet 2”);
s2.Print();
//Change a column, so we know that it works.
s2[2][2] = “!”; s2.Print();
//Now, clear out the original sheet and display it.
s1.Clear();
s1.Print();
}
When the program is run, if you have done everything properly, you should see the output from Listing 39-5 in the shell window.
LISTING 39-5: THE OUTPUT FROM THE SPREADSHEET TEST DRIVER APPLICATION
Sheet: Sheet1 |
|
|
|
|
|
|
|
|
|
Begin |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
Hello |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
(continued)
222 Technique 39: Implementing a Spreadsheet
LISTING 39-5 (continued)
Sheet: |
Sheet 2 |
|
|
Begin |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
* |
Sheet: |
Sheet 2 |
|
|
Begin |
* |
* |
* |
* |
* |
* |
* |
* |
* |
! |
* |
* |
* |
* |
* |
Sheet: |
Sheet1 |
|
|
The output shown indicates the state of the spreadsheet at the time it is displayed. An asterisk (*) is shown in any cell that contains no data, while cells that do contain data are shown with the data value. For example, you will see the string Hello in the center of Sheet1, which was placed there at 5 in the code listing for the main driver. Likewise, the top left corner of Sheet1 contains the string Begin, which was placed there at the following line in the driver program.
We could easily use this spreadsheet class to store data, display it for the user, or manipulate data that is contained in a row/column definition.
The asterisks are simply placeholders to show where the actual column data should be. As you can
see, the data values that we set in our test driver show up where they’re supposed to.
You can’t truly implement a two-dimensional array in C++, since there is no operator [][]. However, if you look at the code, you can see a way to implement an operator that returns another class that implements the same operator. The spreadsheet class implements an operator[] (shown by the 4 in Listing 39-3)
which returns the row requested by the index. |
|
|
|
The row class then implements the opera- |
|
tor[] (shown by the |
3 line in Listing 39-2) |
to return the column requested by the index. That’s why [row][col] = value works.
Part VI
Input and Output