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


 Производные классы позволяют ввести новые операции



Pdf көрінісі
бет158/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   154   155   156   157   158   159   160   161   ...   256
8.4.2 Производные классы позволяют ввести новые операции 
В предыдущем разделе функция сравнения была "встроенной" в теле sort() (просто использовалась 
операция <). Возможно другое решение, когда ее предоставляет сам шаблонный класс Vector. Однако, 
такое решение имеет смысл только при условии, что для типов элементов возможно осмысленное 
понятие сравнения. Обычно в такой ситуации функцию sort() определяют только для векторов, на 
которых определена операция < : 
template void sort(SortableVector& v) 

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

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

temp 

v[j]; 
v[j] 

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

temp; 


Класс SortableVector (сортируемый вектор) можно определить так: 
template class SortableVector 
: public Vector, public Comparator
public: 
SortableVector(int s) : Vector(s) { } 
}; 
Чтобы это определение имело смысл еще надо определить шаблонный класс Comparator 
(сравниватель): 
template class Comparator { 
public: 
inline static lessthan(T& a, T& b) // 
функция "меньше" 

return 
strcmp(a,b)<0; 

// 
... 
}; 
Чтобы устранить тот эффект, что в нашем случае операция < дает не тот результат для типа char*, мы 
определим специальный вариант класса сравнивателя: 
class Comparator
public: 
inline static lessthan(const char* a, const char* b) 
// функция "меньше" 
{ return strcmp(a,b)<0; } 
// 
... 
}; 
Описание специального варианта шаблонного класса для char* полностью подобно тому, как в 
предыдущем разделе мы определили специальный вариант шаблонной функции для этой же цели. 
Чтобы описание специального варианта шаблонного класса сработало, транслятор должен обнаружить 


Бьерн Страуструп.
Язык программирования С++ 
 
218 
его до использования. Иначе будет использоваться создаваемый по шаблону класс. Поскольку класс 
должен иметь в точности одно определение в программе, использовать и специальный вариант класса, 
и вариант, создаваемый по шаблону, будет ошибкой. 
Поскольку у нас уже специальный вариант класса Comparator для char*, специальный вариант класса 
SortableVector для char* не нужен, и можем, наконец, попробовать сортировку: 
void f(SortableVector& vi, 
SortableVector
vc, 
SortableVector
vi2, 
SortableVector
vs) 

sort(vi); 
sort(vc); 
sort(vi2); 
sort(vs); 

Возможно иметь два вида векторов и не очень хорошо, но, по крайней мере, SortableVector является 
производным от Vector. Значит если в функции не нужна сортировка, то в ней и не надо знать о классе 
SortableVector, а там, где нужно, сработает неявное преобразование ссылки на производный класс в 
ссылку на общий базовый класс. Мы ввели производный от Vector и Comparator класс SortableVector 
(вместо того, чтобы добавить функции к классу, производному от одного Vector) просто потому, что 
класс Comparator уже напрашивался в предыдущим примере. Такой подход типичен при создании 
больших библиотек. Класс Comparator естественный кандидат для библиотеки, поскольку в нем можно 
указать различные требования к операциям сравнения для разных типов. 


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




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

    Басты бет