- •Содержание
- •ВВЕДЕНИЕ
- •1.ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ПОДХОД
- •2. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ
- •2.1. Абстрактные типы данных
- •2.2. Базовые принципы объектно-ориентированного программирования
- •2.3. Основные достоинства языка С++
- •2.4. Особенности языка С++
- •2.4.1. Ключевые слова
- •2.4.2. Константы и переменные
- •2.4.3. Операции
- •2.4.4. Типы данных
- •2.4.5. Передача аргументов функции по умолчанию
- •2.5.1. Объект cin
- •2.5.2. Объект cout
- •2.5.3. Манипуляторы
- •3.1. Объекты
- •3.2. Понятие класса
- •3.3. Конструктор копирования
- •3.4. Конструктор explicit
- •3.5. Указатель this
- •3.6. Встроенные функции (спецификатор inline)
- •3.7. Организация внешнего доступа к локальным компонентам класса (спецификатор friend)
- •3.8. Вложенные классы
- •3.9. Static-члены (данные) класса
- •3.10. Компоненты-функции static и const
- •3.11. Proxi-классы
- •3.12. Ссылки
- •3.12.1. Параметры ссылки
- •3.12.2. Независимые ссылки
- •3.13. Пространства имен
- •3.13.3. Ключевое слово using как объявление
- •3.13.4. Псевдоним пространства имен
- •3.14. Практические приемы ограничения числа объектов класса
- •4. НАСЛЕДОВАНИЕ
- •4.1.1. Конструкторы и деструкторы при наследовании
- •4.2. Виртуальные функции
- •4.3. Абстрактные классы
- •4.4. Виртуальные деструкторы
- •4.6. Виртуальное наследование
- •5.2. Перегрузка операторов
- •5.2.2. Перегрузка унарного оператора
- •5.2.3. Дружественная функция operator
- •5.2.4. Особенности перегрузки операции =
- •5.2.5. Перегрузка оператора []
- •5.2.6. Перегрузка оператора ()
- •5.2.7. Перегрузка оператора ->
- •5.2.8. Перегрузка операторов new и delete
- •5.3. Преобразование типа
- •5.3.1. Явные преобразования типов
- •6. ШАБЛОНЫ
- •6.1. Параметризированные классы
- •6.2. Передача в шаблон класса дополнительных параметров
- •6.3. Шаблоны функций
- •6.4. Совместное использование шаблонов и наследования
- •6.5. Шаблоны класса и friend-функции
- •6.6. Некоторые примеры использования шаблона класса
- •6.6.1. Реализация smart-указателя
- •6.6.2. Задание значений параметров класса по умолчанию
- •7.2. Состояние потока
- •7.3. Строковые потоки
- •7.4. Организация работы с файлами
- •7.5. Организация файла последовательного доступа
- •7.6. Создание файла произвольного доступа
- •7.7. Основные функции классов ios, istream, ostream
- •8. ИСКЛЮЧЕНИЯ В С++
- •8.2. Перенаправление исключительных ситуаций
- •8.3. Исключительная ситуация, генерируемая оператором new
- •8.6. Спецификации исключительных ситуаций
- •8.7. Задание собственного неожиданного обработчика
- •9. СТАНДАРТНАЯ БИБЛИОТЕКА ШАБЛОНОВ (STL)
- •9.3. Категории итераторов
- •9.4. Операции с итераторами
- •9.5. Контейнеры последовательностей
- •9.5.2. Контейнер последовательностей list
- •9.5.3. Контейнер последовательностей deque
- •9.6. Ассоциативные контейнеры
- •9.6.1. Ассоциативный контейнер multiset
- •9.6.2. Ассоциативный контейнер set
- •9.6.3. Ассоциативный контейнер multimap
- •9.7.1. Адаптер stack
- •9.7.2. Адаптер queue
- •9.7.3. Адаптер priority_queue
- •9.8. Алгоритмы
- •9.8.1. Алгоритмы сортировки sort, partial_sort, sort_heap
- •9.8.2. Алгоритмы поиска find, find_if, find_end, binary_search
- •9.8.3. Алгоритмы fill, fill_n, generate и generate_n
- •9.8.4. Алгоритмы equal, mismatch и lexicographical_compare
- •9.8.6. Алгоритмы работы с множествами
- •9.8.7. Алгоритмы swap, iter_swap и swap_ranges
- •9.8.8. Алгоритмы copy, copy_backward, merge, unique и reverse
- •10. ПРИМЕРЫ РЕАЛИЗАЦИИ КОНТЕЙНЕРНЫХ КЛАССОВ
- •10.1. Связанные списки
- •10.1.1. Реализация односвязного списка
- •10.2. Реализация бинарного дерева
- •11. ПРОГРАММИРОВАНИЕ ДЛЯ WINDOWS
- •11.1. Система, управляемая сообщениями
- •11.2. Управление графическим выводом
- •11.3. Контекст устройства
- •11.3.1. Экран
- •11.3.2. Принтер
- •11.3.3. Объект в памяти
- •11.3.4. Информационный контекст
- •11.4. Архитектура, управляемая событиями
- •11.5. Исходный текст программы
- •11.7. Некоторые новые типы данных
- •11.8. Венгерская нотация
- •11.9. Точка входа программы
- •11.11. Создание окна
- •11.12. Цикл обработки сообщений
- •11.13. Оконная процедура
- •11.14. Обработка сообщений
- •11.15. Обработка сообщений функцией DefWindowProc
- •11.16. Синхронные и асинхронные сообщения
- •11.17. Еще один метод получения описателя контекста устройства
- •11.19. Полосы прокрутки
- •Литература
//заполнение [first, last +1) числами Фибоначчи
//используя функцию Fibonacci()
generate(start, end, Fibonacci) ;
cout << "numb { " ; // вывод содержимого for(it = start; it != end; it++)
cout << *it << " " ; cout << " }\n" << endl ; return 0;
}
9.8.4. Алгоритмы equal, mismatch и lexicographical_compare
Алгоритмы данной группы используются для выполнения сравнения на
равенство последовательностей значений. |
|
|
|
|
|
Р |
||
#include <vector> |
|
|
|
|
|
|
И |
|
using namespace std; |
|
|
|
|
|
|
||
#include <iostream> |
|
|
|
|
|
У |
|
|
#include <algorithm> |
|
|
|
|
|
|
||
|
|
|
|
Г |
|
|
||
int main() |
|
|
|
|
|
|
||
|
|
|
Б |
|
|
|
||
{ int m1[]={2,3,5,7,12}; |
|
|
|
|
|
|||
int m2[]={2,3,55,7,12}; |
|
|
|
|
|
|||
|
|
|
|
|
|
|
||
std::vector<int> v1(m1,m1+sizeof(m1)/sizeof(int)), |
|
|
|
|
||||
|
|
|
а |
|
|
|
|
|
v2(m2,m2+sizeof(m2)/sizeof(int)), |
|
|
|
|
||||
v3(m1,m1+sizeof(m1)/sizeof(int));к |
|
|
|
|
||||
bool res=equal(v1.begin(), v1.end(),v2.begin()); |
|
|
|
|
|
|||
cout<<"\nВектор v1 "<<(res?"":"не")<<" равен вектору v2"; |
|
|
||||||
res=equal(v1.begin(), v1.end(),v3.begin()); |
|
|
|
|
|
|||
cout<<"\nВектор v1 "<<(res?"":" не ")<<" равен вектору v3"; |
|
|
||||||
|
т |
|
|
|
|
|
|
|
std::pair<std::vector<int>::iterator, |
|
|
|
|
|
|
||
|
о |
|
|
|
|
|
|
|
std::vector<int>::iterator> pr; |
|
|
|
|
|
|||
pr=std::mismatch(v1.begin(),и v1.end(),v2.begin()); |
|
|
|
|
||||
cout<<"\nv1 и v2 имеют различие в позиции " |
|
|
|
|
||||
л |
|
|
|
|
|
|
|
|
<<(pr.first-v1.begin())<<" где v1= "<<*pr.first |
|
|
|
|
||||
<<"ба v2= "<<*pr.second<<'\n'; |
|
|
|
|
|
|
||
char s1[]="abbbw", s2[]="hkc"; |
|
|
|
|
|
|
|
|
и |
|
|
|
|
|
|
|
|
res=std::lexicographical_compare(s1,s1+sizeof(s1)/sizeof(char), |
|
|
||||||
Б |
|
s2,s2+sizeof(s2)/sizeof(char)); |
|
|||||
|
|
|
|
|
|
|
|
|
cout<<s1<<(res?" меньше ":" не меньше ")<<s2<<'\n'; |
|
|
|
return 0;
}
В строке
bool res=equal(v1.begin(), v1.end(),v2.begin());
для сравнения двух последовательностей чисел на равенство используется алго-
222
ритм equal, получающий в качестве аргументов три итератора (по крайней мере для чтения). Если последовательности неравной длины или их элементы не сов- падают, то equal возвращает false (используя функцию operator==).
Имеется также версия equal, принимающая четвертым параметром преди- катную функцию, получающую два сравниваемых элемента и возвращающую значение типа bool. Это может быть полезно для последовательностей объектов или указателей на сравниваемые значения.
Алгоритм mismatch возвращает пару итераторов для двух сравниваемых по- следовательностей (v1 и v2), указывающих позиции, где элементы различаются:
|
std::pair<std::vector<int>::iterator, |
||||||
|
std::vector<int>::iterator> pr; |
|
|||||
|
pr=std::mismatch(v1.begin(), v1.end(),v2.begin()); |
||||||
|
Для определения позиции, в которой векторы различаютсяР, требуется вы- |
||||||
|
|
|
|
|
|
|
У |
полнить pr.first-v1.begin(). Согласно арифметике указателей это соответствует |
|||||||
числу элементов от начала вектора v1 до элемента, отличногоИот соответствую- |
|||||||
щего элемента вектора v2. |
|
|
|
||||
|
Алгоритм lexicographical_compare использует четыре итератора (по крайней |
||||||
мере для чтения) обычно для сравнения строк. ЕслиГэлемент первой последова- |
|||||||
|
|
|
|
|
|
|
а |
тельности (итерируемый первыми двумя итераторами) меньше элемента второй |
|||||||
(два последних итератора), то функция возврБщает true, иначе false. |
|||||||
|
|
|
|
|
|
к |
|
|
|
|
|
|
ие |
|
|
|
9.8.5. Математическ |
алгоритмы |
|||||
|
Приводимая ниже программа демонстрирует использование нескольких |
||||||
|
|
|
|
т |
random_shuffle, count, count_if, min_element, |
||
математических алгори мов: |
|||||||
max_element, accumulate и transform. |
|
||||||
|
|
|
о |
|
|
|
|
|
#include <iostream> |
|
|
|
|||
|
|
и |
|
|
|
|
|
|
#include <algorithm> |
|
|
|
|||
|
#include <functional> |
|
|
|
|||
|
|
л |
|
|
|
|
|
|
#include <vector> |
|
|
|
|
||
|
using namespace std; |
|
|
|
|||
|
// возвращает целое число в диапазоне 0 - (n - 1) |
||||||
и |
|
|
|
|
|
|
|
Б |
int Rand(int n) |
|
|
|
|
||
б{ return rand() % n ; } |
|
|
|
||||
|
|
|
|
int main()
{ const int v_size = 8 ; typedef vector<int > vect; typedef vect::iterator vectIt ; vect Numbers(v_size) ; vectIt start, end, it ;
// инициализация вектора
Numbers[0] = 4 ; Numbers[1] = 10;
223
Numbers[2] = 70 ; |
Numbers[3] = 4 ; |
Numbers[4] = 10; |
Numbers[5] = 4 ; |
Numbers[6] = 96 ; |
Numbers[7] = 100; |
start = Numbers.begin() ; |
|
// location of first |
|
|
|
|
|||||||||||
end = Numbers.end() ; |
|
// one past the location |
|
|
|
||||||||||||
cout << "До выполнения random_shuffle:" << endl ; |
|
|
|
||||||||||||||
cout << "Numbers { " ; |
|
|
|
|
|
|
|
|
|
|
|||||||
for(it = start; it != end; it++) |
|
|
|
|
|
|
|
|
|||||||||
cout << *it << " " ; |
|
|
|
|
|
|
|
|
|
|
|
Р |
|||||
cout << " }" << endl ; |
|
|
|
|
|
|
|
|
|
|
|||||||
random_shuffle(start, end,pointer_to_unary_function<int, int>(Rand)); |
|||||||||||||||||
cout << "После выполнения random_shuffle:" << endl ; |
|
|
|||||||||||||||
cout << "Numbers { " ; |
|
|
|
|
|
|
|
У |
|||||||||
for(it = start; it != end; it++) |
|
|
|
|
Г |
И |
|||||||||||
cout << *it << " " ; |
|
|
|
|
|
|
|
|
|||||||||
cout << " }" << endl ; |
|
|
|
|
|
|
|
Б |
|
|
|
||||||
cout<<"число 4 встречается"<<count(start, end,4)<<" раз"<<endl; |
|
||||||||||||||||
} |
|
|
|
|
|
|
|
|
|
|
|
|
а |
|
|
|
|
Результат работы программы: |
|
|
|
|
|
||||||||||||
До выполнения random_shuffle |
|
|
|
|
|
||||||||||||
Numbers {4 |
10 |
70 |
4 |
|
10 |
4 |
96 |
100} |
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
е |
|
|
|
|||
После выполнения random_shuffle |
|
|
|
|
|||||||||||||
Numbers {10 |
4 |
4 |
|
70 |
|
96 |
100 4 |
10} |
к |
|
|
|
|
||||
число 4 встречается 3 раза |
т |
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|||||||||
Кратко охарактеризуем данные алгоритмы: |
|
|
|
|
|||||||||||||
|
|
|
|
|
|
о |
|
|
|
|
|
|
|
||||
random_shuffle − имеется две версии функции для расположения в произ- |
|||||||||||||||||
|
|
|
|
и |
|
|
|
|
|
|
|
|
|
|
|||
вольном порядке чисел в д апаз не, определяемом аргументами-итераторами; |
|||||||||||||||||
count, count_if – |
сп льзуются для подсчета числа элементов с заданным |
||||||||||||||||
|
|
л |
|
|
|
|
|
|
|
|
|
|
|
|
|||
значением в диапазоне; |
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
б |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
min_element, max element – нахождение min- и max-элемента в диапазоне; |
|||||||||||||||||
accumulate – суммирование чисел в диапазоне; |
|
|
|
|
|||||||||||||
и |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
transform – применение общей функции к каждому элементу вектора. |
|||||||||||||||||
Б |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9.8.6. Алгоритмы работы с множествами |
|
|
|
|
Манипуляция множествами отсортированных значений выполняется ал-
горитмами: includes, set_difference, set_intersection, set_symmetric_difference и set_union. Приводимая ниже программа показывает пример использования ал- горитма includes, проверяющего, входят ли элементы последовательности Deque в вектор Vector.
#include <iostream>
224
#include <algorithm> #include <functional> #include <string> #include <vector> #include <deque> using namespace std;
|
int main() |
|
|
|
|
|
|
{ const int VECTOR_SIZE = 5 ; |
|
||||
|
vector<string > Vector(VECTOR_SIZE) ; |
Р |
||||
|
vector<string >::iterator start1, end1, it1; |
|||||
|
eque<string > Deque ; |
|
||||
|
eque<string >::iterator start2, end2, it2 ; |
|||||
|
Vector[0] = "Коля"; |
|
У |
|||
|
|
// инициализация вектора |
||||
|
Vector[1] = "Аня"; |
|
|
И |
||
|
Vector[2] = "Сергей"; |
|
||||
|
Vector[3] = "Саша"; |
|
|
|
||
|
Vector[4] = "Вася"; |
|
|
|
||
|
start1 = Vector.begin() ; // итератор на началоГVector |
|||||
|
end1 = Vector.end() ; |
|
// итер тор на конец Vector |
|||
|
Deque.push_back("Сергей") ; // инициализацияБ |
последовательности |
||||
|
|
|
|
|
к |
|
|
Deque.push_back("Аня") ; |
|
||||
|
Deque.push_back("Саша") ; а |
|
||||
|
start2 = Deque.begin() ; |
// ит ратор на начало Deque |
||||
|
|
|
т |
// ит ратор на конец Deque |
||
|
end2 = Deque.end() ; |
|
||||
|
sort(start1, end1) ; |
е//сортировка Vector и Deque |
||||
|
|
о |
|
|
|
|
|
sort(start2, end2) ; |
|
|
|
||
|
|
и |
// вывод содержимого Vector и Deque |
|||
|
|
|
||||
|
cout << "Vector { " ; |
|
|
|
||
|
for(it1 = start1; it1 != end1; it1++) |
|
||||
|
cout << *it1 << ", " ; |
|
|
|||
|
б |
|
|
|
|
|
|
cout << " }\n" << endl ; |
|
|
|||
|
coutл<< "Deque { " ; |
|
|
|
||
|
for(it2 = start2; it2 != end2; it2++) |
|
||||
|
cout << *it2 << ", " ; |
|
|
|||
иcout << " }\n" << endl ; |
|
|
||||
Б |
if(includes(start1, end1, start2, end2) ) |
|
||||
cout << "Vector включает Deque" << endl ; |
|
else
cout << "Vector не включает Deque" << endl ; return 0;
}
Несколько слов о других алгоритмах:
set_difference – определяются элементы из первого множества, не входя- 225