Перейти к содержанию

Парадигмы программирования/Обобщенное программирование. Шаблоны классов.

Материал из Викиверситета

Обобщенное программирование (ОП)

[править]

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

Средства языка C++ для ОП

[править]

Шаблоны (англ. template) — средство языка C++, предназначенное для кодирования обобщённых алгоритмов, без привязки к некоторым параметрам (например типам данных, размерам буферов, значениям по умолчанию). В C++ возможно создание шаблонов функций и классов. Например, нам нужно сложить 2 числа:

 int sum_int(int a, int b){
 return a+b;
 }
 double sum_dbl(double a, double b){
 return a+b;
 }

и т.д. для каждого типа нам придется писать свою функцию. Шаблоны позволяют создавать параметризованные классы и функции. Тогда мы можем абстрагироваться от конкретных типов и использовать шаблоны с параметрами. Синтаксис: в начале перед объявлением класса напишем слово template и укажем параметры в угловых скобках:

 # include<stdio.h>
 template<class T>  //тип любой
 int main(){
 return 0;
 }
 T sum (T a, T b){
 return a+b;
 }

Хотя шаблоны предоставляют краткую форму записи участка кода, на самом деле их использование не сокращает исполнимый код, так как для каждого набора параметров компилятор создаёт отдельный экземпляр функции или класса. Ошибки, связанные с использованием конкретных параметров шаблона, нельзя выявить до того, как шаблон использован.

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

Шаблоны классов

[править]

Шаблон класса определяет данные и операции потенциально неограниченного множества родственных классов. Шаблон функции определяет потенциально неограниченное множество родственных (совместно используемых) функций.

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

 template< class T >
 class List
 {
 /* ... */
 public:
   void Add( const T& Element );
   bool Find( const T& Element );
 /* ... */
 };

Специализация шаблонов

[править]

Несколько напоминает перегрузку шаблонов ситуация, когда определяется обычная функция, имя которой совпадает с именем шаблона и список параметров которой соответствует шаблону с некоторым специфическим набором фактических типов. Такую функцию называют специализированной функцией шаблона. Этот прием применяют, когда для некоторого типа или набора типов общий шаблон работать не будет. Когда компилятор встречает вызов какой-то функции, для его разрешения он следует такому алгоритму:

  • Сначала ищется обычная функция с соответствующими параметрами.
  • Если таковой не найдено, компилятор ищет шаблон, из которого можно было бы генерировать функцию с точным соответствием параметров.
  • Если этого сделать невозможно, компилятор вновь рассматривает обычные функции на предмет возможных преобразований типа параметров.

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

Исключения.Обработка исключений

[править]

В языке С++ существует механизм обработки ошибочных ситуаций, называется обработка исключений(англ. exception handline). Обработка исключений по большей части относится к парадигме функционального программирования. для обработки ошибок удобна функция main, поскольку остается активной все время исполнения программы и может обработать исключение в практически любой части программы.Из программы выделяется некоторый блок кода, исполнение которого, предположительно, может привести к возникновению исключительных ситуаций.Для пометки блока используется ключевое слово try(англ.попытаться). Сразу после try-блока необходимо поместить один или больше обработчиков исключений. Он начинается с ключевого слова catch(англ. поймать), сразу после него круглые скобки, внутри них описание формального параметра.Тип параметра задает тип обрабатываемого исключения.

 try{
 while(true){
 Ai.pop_back();
 }
 } catch(const char *msg){
 printf("%s\n",msg);
 return -1;
 }

В некоторых случаях логично использовать обработчик, способный поймать произвольное исключение, независимо от его типа.

 try{
 while(true){
 Ai.pop_back();
 }
 } catch(...)

Работа с исключениями хороша тем, что прежде всего компилятор гарантирует, что прежде чем функция завершится(по исключению или обычным путем)для всех локальных объектов, имеющих деструкторы, эти деструкторы будут корректно вызваны.

 На основе материалов А.В.Столяров. Введение в язык Си++