// 9. Предефиниране на унарни и бинарни операции. Клас Array. // // Fig. 8.4: array1.h // Array class for storing arrays of integers. #ifndef ARRAY1_H #define ARRAY1_H #include using std::ostream; using std::istream; class Array { friend ostream &operator<<( ostream &, const Array & ); friend istream &operator>>( istream &, Array & ); public: Array( int = 10 ); // default constructor Array( const Array & ); // copy constructor ~Array(); // destructor int getSize() const; // return size // assignment operator const Array &operator=( const Array & ); // equality operator bool operator==( const Array & ) const; // inequality operator; returns opposite of == operator bool operator!=( const Array &right ) const { return ! ( *this == right ); // invokes Array::operator== } // end function operator!= // subscript operator for non-const objects returns lvalue int &operator[]( int ); // subscript operator for const objects returns rvalue const int &operator[]( int ) const; private: int size; // array size int *ptr; // pointer to first element of array }; // end class Array #endif /****/ // Fig 8.5: array1.cpp // Member function definitions for class Array #include using std::cout; using std::cin; using std::endl; #include using std::setw; #include // C++ standard "new" operator #include // exit function prototype #include "array1.h" // Array class definition // default constructor for class Array (default size 10) Array::Array( int arraySize ) { // validate arraySize size = ( arraySize > 0 ? arraySize : 10 ); ptr = new int[ size ]; // create space for array for ( int i = 0; i < size; i++ ) ptr[ i ] = 0; // initialize array } // end Array default constructor // copy constructor for class Array; // must receive a reference to prevent infinite recursion Array::Array( const Array &arrayToCopy ) : size( arrayToCopy.size ) { ptr = new int[ size ]; // create space for array for ( int i = 0; i < size; i++ ) ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object } // end Array copy constructor // destructor for class Array Array::~Array() { delete [] ptr; // reclaim array space } // end destructor // return size of array int Array::getSize() const { return size; } // end function getSize // overloaded assignment operator; // const return avoids: ( a1 = a2 ) = a3 const Array &Array::operator=( const Array &right ) { if ( &right != this ) { // check for self-assignment // for arrays of different sizes, deallocate original // left-side array, then allocate new left-side array if ( size != right.size ) { delete [] ptr; // reclaim space size = right.size; // resize this object ptr = new int[ size ]; // create space for array copy } // end inner if for ( int i = 0; i < size; i++ ) ptr[ i ] = right.ptr[ i ]; // copy array into object } // end outer if return *this; // enables x = y = z, for example } // end function operator= // determine if two arrays are equal and // return true, otherwise return false bool Array::operator==( const Array &right ) const { if ( size != right.size ) return false; // arrays of different sizes for ( int i = 0; i < size; i++ ) if ( ptr[ i ] != right.ptr[ i ] ) return false; // arrays are not equal return true; // arrays are equal } // end function operator== // overloaded subscript operator for non-const Arrays // reference return creates an lvalue int &Array::operator[]( int subscript ) { // check for subscript out of range error if ( subscript < 0 || subscript >= size ) { cout << "\nError: Subscript " << subscript << " out of range" << endl; exit( 1 ); // terminate program; subscript out of range } // end if return ptr[ subscript ]; // reference return } // end function operator[] // overloaded subscript operator for const Arrays // const reference return creates an rvalue const int &Array::operator[]( int subscript ) const { // check for subscript out of range error if ( subscript < 0 || subscript >= size ) { cout << "\nError: Subscript " << subscript << " out of range" << endl; exit( 1 ); // terminate program; subscript out of range } // end if return ptr[ subscript ]; // const reference return } // end function operator[] // overloaded input operator for class Array; // inputs values for entire array istream &operator>>( istream &input, Array &a ) { for ( int i = 0; i < a.size; i++ ) input >> a.ptr[ i ]; return input; // enables cin >> x >> y; } // end function // overloaded output operator for class Array ostream &operator<<( ostream &output, const Array &a ) { int i; // output private ptr-based array for ( i = 0; i < a.size; i++ ) { output << setw( 12 ) << a.ptr[ i ]; if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output output << endl; } // end for if ( i % 4 != 0 ) // end last line of output output << endl; return output; // enables cout << x << y; } // end function operator<< /****/ // Fig. 8.6: fig08_06.cpp // Array class test program. #include using std::cout; using std::cin; using std::endl; #include "array1.h" int main() { Array integers1( 7 ); // seven-element Array Array integers2; // 10-element Array by default // print integers1 size and contents cout << "Size of array integers1 is " << integers1.getSize() << "\nArray after initialization:\n" << integers1; // print integers2 size and contents cout << "\nSize of array integers2 is " << integers2.getSize() << "\nArray after initialization:\n" << integers2; // input and print integers1 and integers2 cout << "\nInput 17 integers:\n"; cin >> integers1 >> integers2; cout << "\nAfter input, the arrays contain:\n" << "integers1:\n" << integers1 << "integers2:\n" << integers2; // use overloaded inequality (!=) operator cout << "\nEvaluating: integers1 != integers2\n"; if ( integers1 != integers2 ) cout << "integers1 and integers2 are not equal\n"; // create array integers3 using integers1 as an // initializer; print size and contents Array integers3( integers1 ); // calls copy constructor cout << "\nSize of array integers3 is " << integers3.getSize() << "\nArray after initialization:\n" << integers3; // use overloaded assignment (=) operator cout << "\nAssigning integers2 to integers1:\n"; integers1 = integers2; // note target is smaller cout << "integers1:\n" << integers1 << "integers2:\n" << integers2; // use overloaded equality (==) operator cout << "\nEvaluating: integers1 == integers2\n"; if ( integers1 == integers2 ) cout << "integers1 and integers2 are equal\n"; // use overloaded subscript operator to create rvalue cout << "\nintegers1[5] is " << integers1[ 5 ]; // use overloaded subscript operator to create lvalue cout << "\n\nAssigning 1000 to integers1[5]\n"; integers1[ 5 ] = 1000; cout << "integers1:\n" << integers1; // attempt to use out-of-range subscript cout << "\nAttempt to assign 1000 to integers1[15]" << endl; integers1[ 15 ] = 1000; // ERROR: out of range return 0; } // end main