Иллюстрированный самоучитель по Visual Studio .NET

Контейнеры библиотеки STL. Последовательности типа vector.

Алгоритм переворота последовательности (reverse) может работать как с контейнером, так и с обычным массивом. Для успешной работы ему надо задать диапазон адресов (range). Обратите внимание на то, что в качестве конца последовательности этому алгоритму, как и многим другим в STL, надо подать во втором параметре адрес ar+size, выходящий за пределы массива. Как объяснить тот факт, что шаблон функции reverse, требуя в качестве параметров переменные типа iterator, тем не менее работает, когда ему подают обычный указатель типа Man*? В документации вы можете найти такое объяснение. Указатель – это итератор, но итератор – это не указатель. Итератор – это обобщение (generalization) указателя.

Результат работы программы выглядит так:

Man Vector # Sequence:
1. Mary Poppins, Age: 36
2. Joe Doe, Age: 30
3. Joy Amore, Age: 18
4. Zoran Todorovitch, Age: 27

After reversing the array
1. Zoran Todorovitch, Age: 27
2. Joy Amore, Age: 18
3. Joe Doe, Age: 30
4. Mary Poppins, Age: 36

After default sort # Sequence:
1. Joe Doe, Age: 30
2. Joy Amore, Age: 18
3. Mary Poppins, Age: 36 /
4. Zoran Todorovitch, Age: 27

After predicate LessAge sort # Sequence:
1. Joy Amore, Age: 18
2. Zoran Todorovitch, Age: 27
3. Joe Doe, Age: 30
4. Mary Poppins, Age: 36

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

Сейчас мы намерены создать функциональный объект и использовать его для выбора режима сортировки по имени или по возрасту. Текущий выбор удобно хранить в static-переменной класса Man. Такие переменные, как вы знаете, являются общими для всех объектов класса. Изменяя их значение, можно управлять общими установками, касающимися всех объектов класса. Мы будем управлять текущим режимом сортировки. Для удобства чтения кода введем глобальное определение типа SORTBY – перечисление режимов сортировки:

enum SORTBY { NAME, AGE }; // Режимы сортировки

Декларацию static-переменной следует вставить в public-секцию класса Man:

static SORTBY m_Sort; // Текущий режим сортировки

Определение static-переменной, согласно законам ООП, должно быть глобальным:

//======= Определение и инициализация
SORTBY Man::m_Sort = NAME;

Сам функциональный объект должен быть объявлен как внешняя глобальная friend-конструкция. Вставьте следующее объявление внутрь класса Man:

//======= Функциональный объект имеет доступ к данным
friend struct ManLess;

Затем объявите сам функциональный объект, который, надо признать, имеет несколько непривычный вид:

//======== Функциональный объект
struct ManLess
{
bool operator() (Man& a, Man& b)
{
return a.m_Sort==NAME? (a.m_Name < b.m_Name)
: (a.m_Age < b.m_Age);
}
};
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.