В данной программе объявляется два вида объектов. Объект ob1 использует данные типа int и double, а объект ob2 — символ и указатель на символ. Для этих ситуаций компилятор автоматически генерирует данные и функции, соответствующие способу создания объектов.

Создание обобщенного класса безопасного массива

Прежде чем двигаться дальше, рассмотрим еще одно приложение для обобщенного класса. Как было показано в главе 13, можно перегружать оператор "[]", что позволяет создавать собственные реализации массивов, в том числе и "безопасные массивы", которые обеспечивают динамическую проверку нарушения границ. Как вы знаете, в C++ во время выполнения программы возможен выход за границы массива без выдачи сообщения об ошибке. Но если создать класс, который бы содержал массив, и разрешить доступ к этому массиву только через перегруженный оператор индексации ("[]"), то можно перехватить индекс, соответствующий адресу за пределами адресного пространства массива.

Объединив перегрузку оператора с обобщенным классом, можно создать обобщенный тип безопасного массива, который затем будет использован для создания безопасных массивов, предназначенных для хранения данных любого типа. Такой тип массива и создается в следующей программе.

// Пример создания и использования обобщенного безопасного массива.

#include

#include

using namespace std;

const int SIZE = 10;

template

class atype {

  AType a[SIZE];

 public:

  atype() {

   register int i;

   for(i=0; i

  }

  AType &operator[](int i);

};

// Обеспечение контроля границ для класса atype.

 template

АТуре &atype::operator[](int i)

{

 if(i<0 || i> SIZE-1) {

  cout << "\n Значение индекса ";

  cout << i << " за пределами границ массива.\n";

 }

 return a [i];

}

int main()

{

 atype intob; // массив int-значений

 atype doubleob; // массив double-значений

 int i;

 cout << "Массив int-значений: ";

 for(i=0; i

 for(i=0; i

 cout << '\n';

 cout << "Массив double-значений: ";

 for(i=0; i

 for(i=0; i

 cout << '\n';

 intob[12] = 100; // ошибка времени выполнения!

 return 0;

}

В этой программе сначала создается обобщенный тип безопасного массива, а затем демонстрируется его использование путем создания массива целых чисел и массива double-значений. Было бы неплохо, если бы вы попробовали создать массивы других типов. Как доказывает этот пример, одно из наибольших достоинств обобщенных классов состоит в том, что они позволяют только один раз написать код, отладить его, а затем применять его к данным любого типа, не переписывая его для каждого конкретного приложения.

Использование в обобщенных классах аргументов, не являющихся типами

В template-спецификации для обобщенного класса можно также задавать аргументы, не являющиеся типами. Это значит, что в шаблонной спецификации можно указывать то, что обычно принимается в качестве стандартного аргумента, например, аргумент типа int или аргумент-указатель. Синтаксис (он практически такой же, как при задании обычных параметров функции) включает определение типа и имени аргумента. Вот, например, как можно по-другому реализовать класс безопасного массива, представленного в предыдущем разделе.

// Использование в шаблоне аргументов, которые не являются типами.

#include

#include

using namespace std;

// Здесь элемент int size - это аргумент, не являющийся типом.

template

class atype {

  AType a[size]; // В аргументе size передается длина массива.

 public:

  atype() {

   register int i;

   for(i=0; i

  }

  AType &operator[](int i);

};

// Обеспечение контроля границ для класса atype.

template

AType &atype::operator[](int i)

{

 if(i<0 || i> size-1) {

  cout << "\n Значение индекса ";

  cout << i << " за пределами границ массива.\n";

  exit(1);

 }

 return a[i];

}

int main()

{

 atype intob; // 10-элементный массив целых чисел

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги