Главная->Інформатика та програмування->Содержание->Операция индексации массива ([])

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 8) онлайн

Операция индексации массива ([])

Операция индексации, которая обычно используется для доступа к элементам массива, может быть перегружена. Это полезно в том случае, если вы хотите изменить способ работы C++ с массивами. Например, если вам понадобится создать «безопасный массив», в котором заложена автоматическая проверка ис-

пользуемого для доступа к массиву индекса элемента. Она будет проверять, на- ходитесь ли вы в границах массива. (Вы можете также использовать класс vector, описанный в главе 15 «Стандартная библиотека шаблонов (STL)».)

Для демонстрации перегрузки операции индексации массива мы должны вернуться к другой теме, с которой мы уже встречались в главе 5, — возвращению значений из функции по ссылке. Перегруженная операция индексации должна возвращать свои значения по ссылке. Чтобы показать, почему это так, мы рас- смотрим три программы, которые реализуют «безопасный» массив, каждая при этом использует свой подход для вставки и считывания элементов массива:

два отдельных метода put() и get();

метод access(), использующий возвращение по ссылке;

перегруженная операция [ ], использующая возвращение по ссылке.

Все три программы используют класс safearray, в котором определен массив, состоящий из 100 элементов типа int. И все три проверяют, находится ли эле- мент, к которому мы хотим получить доступ, в границах массива. Функция main() каждой из программ заполняет массив значениями (каждое из которых равно значению индекса массива, умноженному на 10) и затем выводит их все, чтобы показать, что пользователь сделал все правильно.

Два отдельных метода put() и get()

В первой программе мы используем для доступа к элементам массива два мето- да: putel() для вставки элемента в массив и getel() для получения значения нуж- ного нам элемента. Оба метода проверяют, чтобы значение индекса массива вхо- дило в рамки границ массива. То есть оно не должно быть меньше 0 и больше размера массива (минус 1). Приведем листинг программы ARROVER1.

// arrover1.cpp

// демонстрация создания безопасного массива, проверяющего

// свои индексы при использовании

// используются отдельные функции для установки и получения значения

#include <iostream>

using namespace std;

#include <process.h>    // для функции exit

const int LIMIT = 100;  // размер массива

///////////////////////////////////////////////////////////

class safearray

{

  private:

    int arr [ LIMIT ];

  public:

    // установка значения элемента массива

    void putel ( int n, int elvalue )

      {

        if ( n < 0 || n >= LIMIT )

          { cout << "\nОшибочный индекс!"; exit ( 1 ); }

        arr [ n ] = elvalue;

      }

    // получение значения элемента массива

    int getel ( int n ) const

      {

 

if ( n < 0 || n >= LIMIT )

          { cout << "\nОшибочный индекс!"; exit ( 1 ); }

        return arr [ n ];

      }

};

///////////////////////////////////////////////////////////

int main ( )

{

  safearray sa1;

 

  // задаем значения элементов

  for ( int j = 0; j < LIMIT; j++ )

    sa1.putel ( j, j * 10 );

 

  // показываем элементы

  for ( j = 0; j < LIMIT; j++ )

  {

    int temp = sa1.getel ( j );

    cout << "Элемент " << j << " равен " << temp << endl;

  }

 

  return 0;

}

 

Данные помещаются в массив с помощью метода putel() и выводятся на дис- плей с помощью метода getel(). Безопасность массива реализована с помощью вывода сообщения об ошибке при попытке использования индекса, не входяще- го в границы массива. Однако этот формат несколько груб.

Метод access (), использующий возвращение по ссылке

Как оказывается, мы можем использовать один метод для вставки и вывода эле- ментов массива. Секрет этого метода в использовании возвращения значения по ссылке. Это означает, что мы можем записать функцию с левой стороны знака равно, при этом переменной, стоящей справа, будет присвоено значение, возвра- щаемое функцией, как показано в главе 5. Приведем листинг программы ARROVER2.

// arrover2.cpp

// демонстрация создания безопасного массива, проверяющего

// свои индексы при использовании

// используется общая функция для установки и получения значения

#include <iostream>

using namespace std;

#include <process.h>    // для функции exit

const int LIMIT = 100;  // размер массива

///////////////////////////////////////////////////////////

class safearray

{

  private:

    int arr [ LIMIT ];

  public:

    // обратите внимание, что функция возвращает ссылку!

    int& access ( int n )

      {

        if ( n < 0 || n >= LIMIT )

          { cout << "\nОшибочный индекс!"; exit ( 1 ); }

return arr [ n ];

      }

};

///////////////////////////////////////////////////////////

int main ( )

{

  safearray sa1;

 

  // задаем значения элементов

  for ( int j = 0; j < LIMIT; j++ )

    sa1.access ( j ) = j * 10; // используем функцию слева от знака =

 

  // показываем элементы

  for ( j = 0; j < LIMIT; j++ )

  {

    int temp = sa1.access ( j ); // используем функцию справа от знака =

    cout << "Элемент " << j << " равен " << temp << endl;

  }

 

  return 0;

}

 

Строка sal.access ( j ) = j * 10;

означает, что значение j*10 будет помещено в элемент массива arr[j], ссылка на который возвращается методом.

Это использование одного метода для ввода и вывода элементов массива в общем случае немного более удобно, чем использование отдельных методов, на одно имя меньше. Но существует еще лучший способ, вовсе без имен.

Перегруженная операция [], использующая возвращение по ссылке

Мы перегрузим операцию индексации [ ] в классе safearray для использования стандартной записи C++ для доступа к элементам массива. Однако, так как эта операция обычно используется слева от знака равно, наша перегруженная функ- ция должна возвращать свое значение по ссылке, как показано в предыдущей программе. Листинг программы ARROVER3:

// arrover3.cpp

// демонстрация создания безопасного массива, проверяющего

// свои индексы при использовании

// используется перегрузка операции [ ]

#include <iostream>

using namespace std;

#include <process.h>      // для функции exit

const int LIMIT = 100;    // размер массива

///////////////////////////////////////////////////////////

class safearray

{

  private:

    int arr [ LIMIT ];

  public:

// обратите внимание, что функция возвращает ссылку!

    int& operator[ ] ( int n )

      {

        if ( n < 0 || n >= LIMIT )

          { cout << "\nОшибочный индекс!"; exit ( 1 ); }

        return arr [ n ];

      }

};

///////////////////////////////////////////////////////////

int main ( )

{

  safearray sa1;

 

  // задаем значения элементов

  for ( int j = 0; j < LIMIT; j++ )

    sa1[ j ] = j * 10;    // используем функцию слева от знака =

 

  // показываем элементы

  for ( j = 0; j < LIMIT; j++ )

  {

    int temp = sa1 [ j ]; // используем функцию справа от знака =

    cout << "Элемент " << j << " равен " << temp << endl;

  }

 

  return 0;

}

 

В этой программе мы можем использовать обычную запись операции индек- сации массива

sa1[ j ] = j * 10; и

int temp = sa1 [ j ];

для ввода и вывода элементов массива.

 

15