Бьерн Страуструп. Язык программирования С++ Второе дополненное издание


 Передача операций как параметров функций



Pdf көрінісі
бет159/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   155   156   157   158   159   160   161   162   ...   256
8.4.3 Передача операций как параметров функций 
Можно не задавать функцию сравнения как часть типа Vector, а передавать ее как второй параметр 
функции sort(). Этот параметр является объектом класса, в котором определена реализация операции 
сравнения: 
template void sort(Vector& v, Comparator& cmp) 

unsigned n = v.size(); 
for (int i = 0; ifor ( int j = n-1; iif 
(cmp.lessthan(v[j],v[j-1])) 

// меняем местами v[j] и v[j-1] 

temp 

v[j]; 
v[j] 

v[j-1]; 
v[j-1] 

temp; 


Этот вариант можно рассматривать как обобщение традиционного приема, когда операция сравнения 
передается как указатель на функцию. Воспользоваться этим можно так: 
void f(Vector& vi, 
Vector
vc, 
Vector
vi2, 
Vector
vs) 

Comparator 
ci; 
Comparator 
cs; 
Comparator 
cc; 
sort(vi,ci); // sort(Vector&); 
sort(vc,cc); // sort(Vector&); 
sort(vi2,ci); // sort(Vector&); 
sort(vs,cs); // sort(Vector&); 


Бьерн Страуструп.
Язык программирования С++ 
 
219 

Отметим, что включение в шаблон класса Comparator как параметра гарантирует, что функция lessthan 
будет реализовываться подстановкой. В частности, это полезно, если в шаблонной функции 
используется несколько функций, а не одна операция сравнения, и особенно это полезно, когда эти 
функции зависят от хранящихся в том же объекте данных. 
8.4.4 Неявная передача операций 
В примере из предыдущего раздела объекты Comparator на самом деле никак не использовались в 
вычислениях. Это просто "искусственные" параметры, нужные для правильного контроля типов. 
Введение таких параметров достаточно общий и полезный прием, хотя и не слишком красивый. Однако, 
если объект используется только для передачи операции (как и было в нашем случае), т.е. в 
вызываемой функции не используется ни значение, ни адрес объекта, то можно вместо этого 
передавать операцию неявно: 
template void sort(Vector& v) 

unsigned n = v.size(); 
for (int i=0; ifor (int j=n-1; iif 
(Comparator::lessthan(v[j],v[j-1])) 

// меняем местами v[j] и v[j-1] 

temp 

v[j]; 
v[j] 

v[j-1]; 
v[j-1] 

temp; 


В результате мы приходим к первоначальному варианту использования sort(): 
void f(Vector& vi, 
Vector
vc, 
Vector
vi2, 
Vector
vs) 

sort(vi); // sort(Vector&); 
sort(vc); // sort(Vector&); 
sort(vi2); // sort(Vector&); 
sort(vs); // sort(Vector&); 

Основное преимущество этого варианта, как и двух предыдущих, по сравнению с исходным вариантом 
в том, что часть программы, занятая собственно сортировкой, отделена от частей, в которых находятся 
такие операции, работающие с элементами, как, например lessthan. Необходимость подобного 
разделения растет с ростом программы, и особенный интерес это разделение представляет при 
проектировании библиотек. Здесь создатель библиотеки не может знать типы параметров шаблона, а 
пользователи не знают (или не хотят знать) специфику используемых в шаблоне алгоритмов. В 
частности, если бы в функции sort() использовался более сложный, оптимизированный и рассчитанный 
на коммерческое применение алгоритм, пользователь не очень бы стремился написать свою особую 
версию для типа char*, как это было сделано в $$8.4.1. Хотя реализация класса Comparator для 
специального случая char* тривиальна и может использоваться и в других ситуациях. 


Достарыңызбен бөлісу:
1   ...   155   156   157   158   159   160   161   162   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет