Пример класса с двумя обобщенными типами данных



 

Шаблонный класс может иметь несколько обобщенных типов данных. Для этого достаточно объявить все нужные типы данных в template ‑спецификации в виде элементов списка, разделяемых запятыми. Например, в следующей программе создается класс, который использует два обобщенных типа данных.

 

 

Эта программа генерирует такие результаты.

 

 

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

 

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

 

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

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

 

 

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

 

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

 

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

 

 

Рассмотрим внимательно template ‑спецификацию для класса atype . Обратите внимание на то, что аргумент size объявлен с указанием типа int . Этот параметр затем используется в теле класса atype для объявления размера массива a . Несмотря на то что в исходном коде программы член size имеет вид "переменной", его значение известно уже во время компиляции. Поэтому его можно успешно использовать для установки размера массива. Кроме того, значение "переменной" size используется для контроля выхода за границы массива в операторной функции operator[]() . Обратите также внимание на то, как в функции main() создается массив целых чисел и массив значений с плавающей точкой. При этом размер каждого из них определяется вторым параметром template ‑спецификации.

На тип параметров, которые не представляют типы, налагаются ограничения. В этом случае разрешено использовать только целочисленные типы, указатели и ссылки. Другие типы (например, float) не допускаются. Аргументы, которые передаются параметру, не являющемуся типом, должны содержать либо целочисленную константу, либо указатель или ссылку на глобальную функцию или объект. Таким образом, эти "нетиповые" параметры следует рассматривать как константы, поскольку их значения не могут быть изменены. Например, в теле функции operator[]() следующая инструкция недопустима:

 

 

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

Как показывает пример создания безопасного массива, использование "нетиповых" параметров весьма расширяет сферу применения шаблонных классов. И хотя информация, передаваемая через "нетиповой" аргумент, должна быть известна во время компиляции, малость этого ограничения несравнима с достоинствами, предлагаемыми такими параметрами.

Шаблонный класс queue , представленный выше в этой главе, также выиграл бы от применения к нему "нетипового" параметра, задающего размер очереди. В качестве упражнения попробуйте усовершенствовать класс queue самостоятельно.

 


Дата добавления: 2018-09-22; просмотров: 329; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!