How to Use Operators Overloading with Arrays in C++

We want to implement array class with the following specifications: - range checking. - array assignment. - arrays that know their size. - compare arrays using '==' and '!=' operators. In the next example we will implement a simple class for integers is called Array, it has the previous specifications, and it has the following structure:
  1. class Array {
  2.    friend ostream &operator<<( ostream &, const Array & );
  3.    friend istream &operator>>( istream &, Array & );
  4.    public:
  5.      Array( int = 10 );  // default constructor  
  6.      Array( const Array & );  // copy constructor  
  7.      ~Array();  // destructor  
  8.      int getSize() const;  // return size
  9.      const Array &operator=( const Array & ); // assign arrays
  10.      bool operator==( const Array & ) const; // compare equal
  11.  
  12.      // Determine if two arrays are not equal and
  13.      // return true, otherwise returnfalse (uses operator==).
  14.      bool operator!=( const Array &right ) const;
  15.  
  16.      int &operator[]( int );  // subscript operator
  17.      const int &operator[]( int ) const;  // subscript operator
  18.      static int getArrayCount();  // Return count of
  19.      // arrays instantiated.
  20.    private:
  21.      int size; // size of the array
  22.      int *ptr; // pointer to first element of array
  23.      static int arrayCount;  // # of Arrays instantiated
  24. };
Functions Implementation: 1- Default Constructor:
  1. // Default constructor for class Array (default size 10)
  2. Array::Array( int arraySize )
  3. {
  4.    size = (arraySize > 0 ?arraySize : 10 );
  5.    ptr = new int[ size ]; // create space for array
  6.    assert(ptr != 0 );  // terminate if memory not allocated
  7.    ++arrayCount;  // count one more object
  8.  
  9.    for ( int i = 0; i < size; i++ )
  10.       ptr[ i ] = 0;  // initialize array
  11. }
2- Copy Constructor:
  1. // Copy constructor for class Array
  2. // must receive a reference to prevent infinite recursion
  3. Array::Array( constArray &init ) : size( init.size )
  4. {
  5.    ptr = new int[ size ]; // create space for array
  6.    assert(ptr != 0 );  // terminate if memory not allocated
  7.    ++arrayCount;  // count one more object
  8.  
  9.    for ( int i = 0; i < size; i++ )
  10.      ptr[ i ] = init.ptr[ i ];  // copy init into object
  11. }
3- Destructor:
  1. // Destructor for class Array
  2. Array::~Array()
  3. {
  4.    delete [] ptr;  // reclaim space for array
  5.    --arrayCount;  // one fewer object
  6. }
4- Get Size:
  1. // Get the size of the array
  2. int Array::getSize() const
  3. {
  4.   return size;
  5. }
5- Overloaded Assignment Operator:
  1. // const return avoids: ( a1 = a2 ) = a3
  2. const Array &Array::operator=( const Array &right )
  3. {
  4.    if ( &right != this )
  5.    {  // check for self-assignment
  6.  
  7.      // for arrays of different sizes, deallocateoriginal
  8.      // left side array, then allocate new left side array.
  9.      if ( size != right.size )
  10.      {
  11.          delete []ptr;  // reclaim space
  12.          size = right.size;  // resize this object
  13.          ptr = newint[ size ]; // create space for array copy
  14.          assert( ptr != 0 );  // terminate if not allocated
  15.      }
  16.  
  17.      for ( int i = 0; i < size; i++ )
  18.          ptr[ i ] = right.ptr[ i ];  // copy array into object
  19.    }
  20.  
  21.    return *this;  // enables x = y = z;
  22. }
6- Determine If Two Arrays are Equal:
  1. // Determine if two arrays are equal and
  2. // return true, otherwise return false.
  3. bool Array::operator==( const Array &right ) const
  4. {
  5.     if ( size != right.size )
  6.       return false;  // arrays of different sizes
  7.  
  8.     for ( int i = 0; i < size; i++ )
  9.       if ( ptr[ i ] != right.ptr[ i ] )
  10.          return false; // arrays are not equal
  11.  
  12.     return true;  // arrays are equal
  13. }
7- Overloaded Subscript Operator:
  1. // Overloaded subscript operator for non-const Arrays
  2. // reference return creates an lvalue
  3. int &Array::operator[]( int subscript )
  4. {
  5.    // check for subscript out of range error
  6.    assert( 0 <= subscript && subscript < size );
  7.    return ptr[ subscript ]; // reference return
  8. }
8- Overloaded Subscript Operator for Const Arrays:
  1. <code></code>
  2. // Overloaded subscript operator for const Arrays
  3. // const reference return creates an rvalue
  4. const int &Array::operator[]( int subscript ) const
  5. {
  6.    // check for subscript out of range error
  7.    assert( 0 <= subscript && subscript < size );
  8.  
  9.    return ptr[ subscript ]; // const reference return
  10. }
9- Return the Number of Array Objects Instantiated:
  1. // Return the number of Array objects instantiated
  2. // static functions cannot be const
  3. int Array::getArrayCount()
  4. {
  5.    return arrayCount;
  6. }
10- Overloaded Input Operator:
  1. // Overloaded input operator for class Array;
  2. // inputs values for entire array.
  3. istream &operator>>( istream &input, Array &a )
  4. {
  5.    for ( int i = 0; i < a.size; i++ )
  6.      input >> a.ptr[ i ];
  7.  
  8.    return input;  // enables cin >> x >> y;
  9. }
11- Overloaded Output Operator:
  1. // Overloaded output operator for class Array
  2. ostream &operator<<( ostream &output, constArray &a )
  3. {
  4.    int i;
  5.  
  6.    for ( i = 0; i < a.size; i++ )
  7.    {
  8.       output << setw( 12 ) << a.ptr[ i ];
  9.  
  10.       if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output
  11.           output <<endl;
  12.    }
  13.  
  14.    if ( i % 4 != 0 )
  15.       output << endl;
  16.  
  17.    return output;  // enables cout<< x << y;
  18. }
After we implement all functions we test them:
  1. int main()
  2. {
  3.     // no objects yet
  4.     cout << "# of arrays instantiated = "
  5.     << Array::getArrayCount() << '\n';
  6.     // create two arrays andprint Array count
  7.     Array integers1( 7 ), integers2;
  8.     cout << "# of arrays instantiated = "
  9.     << Array::getArrayCount() << "\n\n";
  10.  
  11.     // print integers1 size and contents
  12.     cout << "Size of array integers1 is "
  13.     << integers1.getSize()
  14.     << "\nArrayafter initialization:\n"
  15.     << integers1 << '\n';
  16.  
  17.     // print integers2 size and contents
  18.     cout << "Size of array integers2 is "  
  19.     << integers2.getSize()
  20.     << "\nArrayafter initialization:\n"
  21.     << integers2 << '\n';
  22.  
  23.     // input and print integers1 and integers2
  24.     cout << "Input 17 integers:\n";
  25.     cin >> integers1 >> integers2;
  26.     cout << "After input, the arrays contain:\n"
  27.     << "integers1:\n" << integers1
  28.     << "integers2:\n" << integers2 << '\n';
  29.  
  30.    // use overloaded inequality (!=) operator
  31.    cout << "Evaluating: integers1 != integers2\n";
  32.    if ( integers1 != integers2 )
  33.       cout<< "They are not equal\n";
  34.  
  35.    // create array integers3 using integers1 as an
  36.    // initializer; print size and contents
  37.    Array integers3( integers1 );
  38.    << "\nSizeof array integers3 is "
  39.    << integers3.getSize()
  40.    << "\nArrayafter initialization:\n"
  41.    << integers3 << '\n';
  42.  
  43.    // use overloaded assignment (=) operator
  44.    cout << "Assigning integers2 to integers1:\n";
  45.    integers1 = integers2;
  46.    cout << "integers1:\n" << integers1
  47.    << "integers2:\n" << integers2 << '\n';
  48.  
  49.    // use overloaded equality (==) operator
  50.    cout << "Evaluating: integers1 == integers2\n";
  51.    if ( integers1 == integers2 )
  52.      cout<< "They are equal\n\n";
  53.  
  54.    // use overloaded subscript operator to create rvalue
  55.    cout << "integers1[5] is " << integers1[ 5 ] << '\n';
  56.  
  57.    // use overloaded subscript operator to create lvalue
  58.    cout << "Assigning 1000 to integers1[5]\n";
  59.    integers1[ 5 ] = 1000;
  60.    cout << "integers1:\n" << integers1 << '\n';
  61.  
  62.    // attempt to use out of range subscript
  63.    cout << "Attempt to assign 1000 to integers1[15]" << endl;
  64.    integers1[ 15 ] = 1000;  // ERROR: out of range
  65.  
  66.    return 0;
  67. }
The output:
# of arrays instantiated = 0
# of arrays instantiated = 2
Size of array integers1 is 7
Array after initialization:
0 0  0 0
0 0 0
Size of array integers2 is 10
Array after initialization:
0 0  0 0
0 0  0 0
0 0
Input 17 integers:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
After input, the arrays contain:
integers1:
1 2  3 4
5 6 7
integers2:
8 9 10 11
12 13 14 15
16 17
Evaluating: integers1 != integers2
They are not equal
Size of array integers3 is 7
Array after initialization:
1 2  3 4
5 6 7
Assigning integers2 to integers1:
integers1:
8 9 10 11
12 13 14 15
16 17
integers2:
8 9 10 11
12 13 14 15
16 17

Evaluating: integers1 == integers2
They are equal
integers1[5] is 13
Assigning 1000 to integers1[5]
integers1:
8 9 10 11
12 1000 14 15
16 17
Attempt to assign 1000 to integers1[15]
Assertion failed: 0 = subscript &&subscript  size, file Array1.cpp, 
line 95 abnormal program termination
Note: You can find the full source code of this example in code.zip file.
Tags

Add new comment