You must include the header file apvector.h in any source file that uses apvector. Then you're free to declare variables of type apvector, as follows:
apvectorintVector; // initial size of 0 apvector intVector(10); // initial size of 10 apvector initializedVector(20, 0); // size 20, all values set to 0 apvector aLine(80); apvector aBlankLine(80, ' '); // 80 blanks apvector Averages(8); apvector Flags(4);
There is no .cpp to include in your project. It actually gets included by the apvector.h file. This is only done when you're working with a template class, never with a regular class.
This is included in the quick reference provided to students during the AP exam:
templateclass apvector // public member functions // constructors/destructor apvector(); // default constructor (size == 0) apvector(int size); // initial size of vector is size apvector(int size, const itemType& fillValue); // all entries == fillValue apvector(const apvector& vec); // copy constructor ~apvector(); // destructor // assignment const apvector& operator=(const apvector& vec); // accessors int length() const; // capacity of vector // indexing itemType& operator[](int index); // indexing with range checking const itemType& operator[](int index) const; // indexing with range checking // modifiers void resize(int newSize); // change the size dynamically; can result in losing values
Certain issues come into play when dealing with dynamic allocation of memory (that is, allocation at run-time rather than at compile-time). There is dynamic memory allocation happening in the implementation of apvector, which is why it has a couple of specially identified member functions.
A copy constructor is called automatically when a class instance is passed as a call-by-value argument, or when one is returned as the value of a function call. The constructor takes one argument, which is constant call-by-reference and of the same class that contains it. The copy constructor is necessary when memory is dynamically allocated, to explicitly allocate new memory and copy values into it.
A destructor is called automatically when a class instance variable is destroyed. For local variables and call-by-value parameters, this happens when the function in which they're defined ends; for global variables, it's called when the program ends. Usually the destructor explicitly frees up any memory used for storing the private members of the class. The apvector destructor releases the memory used to store the elements of the vector. The destructor has the same name as the class, preceded by a tilde (~).
#include "iostream.h" #include "apvector.h" const int Nstudents = 10; int main() { int i; apvectorExamScores(Nstudents); // this is the only line that's different! double sum = 0.0, average; // Get input values cout << "Enter " << Nstudents << " scores:" << endl; for (i = 0; i < Nstudents; i++) { cin >> ExamScores[i]; sum += ExamScores[i]; } // Compute and display average average = sum / Nstudents; cout << "The average is " << average << endl; // Find and display numbers above the average for (i = 0; i < Nstudents; i++) if (ExamScores[i] > average) cout << ExamScores[i] << " "; cout << endl; return 0; }
apvector provides range checking. If an out-of-range subscript is detected at run time, an error message is generated and program execution ends. For instance, if I run this code:
apvectorExamScores(10); for (int i = 0; i <= 10; i++) { ExamScores[i] = i + 1; cout << ExamScores[i] << endl; }
I get this output:
1 2 3 4 5 6 7 8 9 10 Illegal vector index: 10 max index = 9
I also get an error message box that says "Program aborted".
Again, apvectors should be passed to functions using call-by-reference rather than call-by-value. Note the use of the method length() in this function definition.
void PrintArray(const apvector& aVector) { for (int i = 0; i < aVector.length(); i++) cout << aVector[i] << endl; }
Another example, this one with an output parameter. Note the use of the method resize() in this function definition.
void Reverse(const apvector& a, apvector & b) { int i, n = a.length(); b.resize(n); for (i = 0; i < n; i++) b[i] = a[n - i - 1]; }
(a) | Write and test a version of the Reverse function which, instead of using an output parameter, uses a return value. The prototype will be: apvector |
(b) | Write and test a function which returns an apvector consisting of every other element of its single apvector argument. For instance, called on a vector with elements 1, 2, 3, 4, 5, it should return a vector containing the elements 1, 3, 5. |
templateclass apmatrix // public member functions // constructors/destructor apmatrix(); // default size 0 x 0 apmatrix(int rows, int cols); apmatrix(int rows, int cols, const itemType& fillValue); apmatrix(const apmatrix& mat); ~apmatrix(); // assignment const apmatrix& operator=(const apmatrix& rhs); // accessors int numrows() const; int numcols() const; // indexing const apvector & operator[](int k) const; apvector & operator[](int k); // modifiers void resize(int newRows, int newCols);
int main() { apmatrixboard(3, 3, ' '); board[1][1] = 'X'; board[0][2] = 'O'; DisplayBoard(board); return 0; } void DisplayBoard(const apmatrix & theBoard) { int row, column; for (row = 0; row < theBoard.numrows(); row++) { if (row != 0) cout << "---+---+---" << endl; for (column = 0; column < theBoard.numcols(); column++) { if (column != 0) cout << "|"; cout << " " << board[row][column] << " "; } cout << endl; } }
(a) | Write a program which builds a multiplication table in an apmatrix. Input the number of rows and columns from the user. Then write a function to display the contents of the table. |
(b) | Write a function (which you can test on your multiplication table) that counts the number of even numbers in an apmatrix. |