SOLUTIONS ■ 469 int *a3, len3 = len1 + len2; a3 = splice( a1, len1, a2, len2, pos); if( a3 == NULL) cerr << "\n Invalid position!\n" << endl; else { cout << " The new spliced array: " << endl; for( i = 0; i < len3; ++i) cout << setw(12) << a3[i]; cout << endl; } delete[] a1; delete[] a2; delete[] a3; return 0; } // // Function splice() inserts the array v2 into v1 // starting at position pos. int *splice( int v1[], int len1, int v2[], int len2, int pos) { if( pos < 0 || pos > len1) return NULL; int i = 0, i1 = 0, i2 = 0; int *v = new int[len1+len2]; for( i = 0, i1 = 0; i1 < pos; ++i, ++i1) // 1st part v[i] = v1[i1]; for( i2 = 0; i2 < len2; ++i, ++i2) // 2nd part v[i] = v2[i2]; for( ; i1 < len1; ++i, ++i1) // 3rd part v[i] = v1[i1]; return v; } 470 ■ CHAPTER 21 DYNAMIC MEMORY ALLOCATION Exercise 2 // // merge.cpp // Implements the merge algorithm. // #include <iostream> #include <iomanip> #include <cstdlib> #include <ctime> using namespace std; // Prototypes: void selectionSort( int arr[], int len); int *merge( int v1[], int len1, int v2[], int len2); int main() { cout << "\n * * * The Merge Algorithm * * *\n" << endl; int i, len1 = 10, len2 = 20; int *a1 = new int[len1], *a2 = new int[len2]; // Initialize the random number generator // with the current time: srand( (unsigned)time(NULL)); for( i=0; i < len1; ++i) // Initialized arrays: a1[i] = rand(); for( i=0; i < len2; ++i) a2[i] = rand(); selectionSort( a1, len1); // To sort array a1. selectionSort( a2, len2); // To sort array a2. // Output the arrays: cout << "The sorted arrays:" << endl; cout << "1st array: " << endl; for( i = 0; i < len1; ++i) cout << setw(12) << a1[i]; cout << endl; cout << "2nd array: " << endl; for( i = 0; i < len2; ++i) cout << setw(12) << a2[i]; cout << endl; int *a3, len3; a3 = merge( a1, len1, a2, len2); len3 = len1 + len2; SOLUTIONS ■ 471 cout << "The new merged array: " << endl; for( i = 0; i < len3; ++i) cout << setw(12) << a3[i]; cout << endl; delete[] a1; delete[] a2; delete[] a3; return 0; } // // Function selectionSort(). inline void swap( int& a, int& b) // To swap. { int temp = a; a = b; b = temp; } void selectionSort( int *arr, int len) { register int *p, *minp; // Pointer to array elements, int *last = arr + len-1; // Pointer to the last element for( ; arr < last; ++arr) { minp = arr; // Search minimum for( p = arr+1; p <= last; ++p) // starting at if( *minp > *p) // position arr. minp = p; swap( *arr, *minp); // To swap. } } // // merge() : Merges two sorted arrays to create // a new sorted array. int *merge( int v1[], int len1, int v2[], int len2) { int i = 0, i1 = 0, i2 = 0; int *v = new int[len1+len2]; // New int array. for( i=0; i1 < len1 && i2 < len2; ++i) { if( v1[i1] <= v2[i2]) v[i] = v1[i1++]; else v[i] = v2[i2++]; } if( i1 < len1) // Copy the rest of v1 or v2. while( i1 < len1) v[i++] = v1[i1++]; else while( i2 < len2) v[i++] = v2[i2++]; return v; } 472 ■ CHAPTER 21 DYNAMIC MEMORY ALLOCATION Exercise 3 // // date.h : Defines the class Date. // // date.cpp // Implements the methods of class Date, // which are not inline defined. // // // These files are left unchanged // from Chapter 14 (solutions). // // // List.h // Defines the classes ListEl and List // to represent a linked list. // #ifndef _LIST_H_ #define _LIST_H_ #include "Date.h" #include <iostream> #include <iomanip> using namespace std; class ListEl { private: Date date; // Date double amount; // Amount of money ListEl* next; // Pointer to successor public: ListEl( Date d = Date(1,1,1), double b = 0.0, ListEl* p = NULL) : date(d), amount(b), next(p) {} // Access methods const Date& getDate() const { return date; } void setDate() // Sets the current date { date.setDate(); } bool setDate( int day, int month, int year) { return setDate( day, month, year); } SOLUTIONS ■ 473 double getAmount() const { return amount; } void setAmount(double a) { amount = a; } ListEl* getNext() const { return next; } friend class List; }; // Output an element ostream& operator<<( ostream& os, const ListEl& le); // // Defines the List class class List { private: ListEl* first, *last; public: List(){ first = last = NULL; } // Constructor ~List(); // Destructor // Access first and last elements: ListEl* front() const { return first; } ListEl* back() const { return last; } // Appends a new element at the end of the list: void pushBack(const Date& d, double b); // Deletes an element at the beginning of the list. void popFront(); }; // Outputs the list ostream& operator<<( ostream& os, const List& le); #endif // _LIST_H_ // // List.cpp // Implements the methods of class List, // which are not previously defined inline. // #include "List.h" // Destructor of the list: List::~List() { ListEl *pEl = first, *next = NULL; for( ; pEl != NULL; pEl = next) { next = pEl->next; delete pEl; } } 474 ■ CHAPTER 21 DYNAMIC MEMORY ALLOCATION // Appends a new element at the end of the list: void List::pushBack(const Date& d, double b) { ListEl *pEl = new ListEl( d, b); if( last == NULL) // List empty? first = last = pEl; else last->next = pEl, last = pEl; } // Deletes an element from the beginning of the list. void List::popFront() { if( first != NULL) // Not empty? { ListEl *pEl = first; // Save the first element. first = first->next; // Move to the next element. delete pEl; // Former first element if( first == NULL) // Empty now? last = NULL; } } // Global functions for output // Outputs an element: ostream& operator<<( ostream& os, const ListEl& le) { os << le.getDate().asString() << " Amount: "; os << fixed << setprecision(2) << setw(10) << le.getAmount(); return os; } // Outputs the list: ostream& operator<<( ostream& os, const List& List) { ListEl *pEl = List.front(); if( pEl == NULL) os << "The list is empty!" << endl; for( ; pEl != NULL; pEl = pEl->getNext() ) os << *pEl << endl; return os; } SOLUTIONS ■ 475 // // List_t.cpp // Tests the List class. // #include "List.h" int main() { cout << "\n * * * Testing the class list * * *\n" << endl; List aList; // A list cout << aList << endl; // List is still empty. cout << "\nEnter account changes (Date and Amount)" "\n(Type invalid input to quit, e.g. q):\n"; Date date; int month, day, year; char c; double amount; while( true) { cout << "Date format Month-Day-Year : "; if( !(cin >> month >> c >> day >> c >> year) || ! date.setDate( month, day, year) ) break; // Invalid date. cout << "Account change: "; if( !(cin >> amount) ) break; aList.pushBack( date, amount); } cout << "\nContent of the list:\n"; cout << aList << endl; cout << "\nRemoving the first element of the list:\n"; ListEl *ptrEl = ptrEl = aList.front(); if( ptrEl != NULL) { cout << "Deleting: " << *ptrEl << endl; aList.popFront(); } cout << "\nContent of the list:\n"; cout << aList << endl; return 0; } This page intentionally left blank 477 Dynamic Members This chapter describes how to implement classes containing pointers to dynamically allocated memory.These include ■ your own copy constructor definition and ■ overloading the assignment operator. A class designed to represent arrays of any given length is used as a sample application. chapter 22 478 ■ CHAPTER 22 DYNAMIC MEMBERS 4.1 6.5 8.2 2.7 Object fArr arrPtr max: 10 cnt: 4 // A class representing dynamic arrays of floats. // class FloatArr { private: float* arrPtr; // Dynamic member int max; // Maximum quantity without // reallocating new storage. int cnt; // Number of present elements public: // Public methods here }; ■ MEMBERS OF VARYING LENGTH An object of class FloatArr in memory Data members of class FloatArr . selectionSort(). inline void swap( int& a, int& b) // To swap. { int temp = a; a = b; b = temp; } void selectionSort( int *arr, int len) { register int *p, *minp; // Pointer to array elements, int *last. memory.These include ■ your own copy constructor definition and ■ overloading the assignment operator. A class designed to represent arrays of any given length is used as a sample application. chapter 22 478 ■ CHAPTER. application. chapter 22 478 ■ CHAPTER 22 DYNAMIC MEMBERS 4.1 6.5 8.2 2.7 Object fArr arrPtr max: 10 cnt: 4 // A class representing dynamic arrays of floats. // class FloatArr { private: float* arrPtr; // Dynamic member int