
- •Тема 1: Динамическая память и интеллектуальные указатели
- •1. Особенности использования динамической памяти (распределяемая память, heap, freestore), стека. Примеры использования.
- •2. Особенности выделения и освобождения памяти для автоматических глобальных и локальных объектов, статических глобальных и локальных объектов. Примеры использования.
- •3. Операторы new и delete при работе с динамической памятью. Свойства указателей, передаваемых оператору delete. Примеры использования.
- •4. Утечка памяти (memory leak). Потерянный указатель (dangling pointer, wild pointer). Примеры использования.
- •5. Проблемы, связанных с использованием операторов new и delete при управлении динамической памятью. Примеры использования.
- •6. Динамически создаваемые объекты (dynamically allocated objects). Интеллектуальные указатели (smart pointers): преимущества, недостатки, особенности использования, различия. Примеры использования.
- •8. Класс интеллектуального указателя shared_ptr. Методы класса указателя shared_ptr. Особенности и примеры использования.
- •9. Копирование и присваивание указателей shared_ptr. Примеры использования.
- •10. Создание и использование объектов интеллектуальных указателей. Примеры.
- •11. Функция make_shared(). Использование функции make_shared() для создания и инициализации объектов интеллектуальных указателей. Примеры использования.
- •12. Счетчик ссылок (reference count), счетчик слабых ссылок (weak count), функция-удалитель (deleter), выделитель памяти (allocator). Примеры использования.
- •13. Использование ключевого слова auto. Примеры использования.
- •14. Классы, ресурсы которых имеют динамическую продолжительность существования. Случаи их использования. Совместное использование данных двумя объектами. Примеры использования.
- •15. Использование оператора new для динамического резервирования памяти и инициализации объектов. Примеры использования.
- •17. Особенности создание пользовательского класса умного указателя (smart pointer). Перечень необходимых условий для реализации пользовательского класса умного указателя. Пример использования.
- •18. Особенности копирования, присваивания и удаления объектов при создании пользовательского класса умного указателя (smart pointer). Пример использования.
- •19. Размещающий оператор new (placement new). Передача ему объекта nothrow. Пример использования.
- •20. Особенности исчерпания памяти. Исключения, возникающие при исчерпании памяти. Пример использования.
- •21. Время жизни динамически создаваемых объектов. Примеры использования.
- •22. Присваивание указателю значения nullptr. Примеры использования.
- •23. Использование указателя shared_ptr совместно с оператором new. Примеры использования.
- •24. Особенности совместного использования обычных указателей и интеллектуальных. Примеры использования.
- •30. Передача в функцию и возврат из функции указателя типа unique_ptr. Примеры использования.
- •31. Использование класса auto_ptr. Особенности и пример использования.
- •32. Передача функции удаления указателю unique_ptr. Примеры использования.
- •33. Класс интеллектуального указателя weak_ptr. Методы класса указателя weak_ptr. Особенности и пример использования.
- •34. Динамические массивы. Особенности работы с динамическими массивами. Особенности резервирования памяти для массивов. Динамическое резервирование пустого массива. Примеры использования
- •35. Оператор new и динамические массивы. Класс bad_array_new_length. Примеры использования.
- •36. Инициализация массива динамически созданных объектов встроенных и пользовательских типов. Примеры использования.
- •37. Особенности освобождение памяти, выделенной для динамических массивов. Примеры использования.
- •38. Взаимодействие интеллектуальных указателей (класс unique_ptr) и динамических массивов. Примеры использования.
- •39. Класс Allocator и специальные алгоритмы. Примеры использования.
- •40. Алгоритмы копирования и заполнения неинициализированной памяти. Примеры использования
- •1. Особенности обработки исключительных ситуаций с использованием функции abort() и exit(). Преимущества и недостатки. Примеры использования.
- •2. Особенности обработки исключительных ситуаций с помощью возврата кода ошибки. Преимущества и недостатки. Примеры использования.
- •4. Роль типа исключения в его обработке. Охранный блок, блок перехвата. Использование механизма обработки исключений. Примеры использования.
- •5. Использование объектов классов в качестве исключений. Одинаковые свойства и различия операторов throw и return. Примеры использования.
- •7. Алгоритм раскручивания стека. Раскручивание стека при нормальном и аварийном завершении программы. Пример использования.
- •8. Понятие абсолютного обработчика, его синтаксис, особенности использования. Пример использования.
- •9. Класс exception. Методы класса exception. Использование наследования класса exception. Пример использования.
- •11. Исключение bad_alloc и операция new. Примеры использования. Использование нулевого указателя и операции new. Примеры использования.
- •12. Использование исключений вместе с классами и наследованием. Особенности использования вложенных классов.
- •13. Потеря исключений. Неперехваченное исключение. Использование функций terminate() и set_terminate().
- •14. Непредвиденное исключение. Использование функций unexpected() и set_unexpected(). Исключение типа std::bad_exception.
- •15. Предостережения относительно использования исключений. Использование и управление исключениями в современных языках программирования.
- •4. Изменение основания системы счисления, используемого для отображения данных. Набор констант типа fmtflags (константы форматирования), решаемые ими задачи.
- •7. Istream как псевдоним шаблона класса basic_istream. Взаимосвязь основных классов ввода/вывода. Ввод данных с помощью объекта cin
- •Istream и ostream как специализации для специализаций char. Wistream и wostream как специализации для типа wchar_t.
- •10. Класс basic_iostream. Iostream как псевдоним шаблона класса basic_iostream. Взаимосвязь основных классов ввода/вывода
- •12. Объекты wcout, wcin, wclog, wcerr, cout, cin, clog, cerr. Особенности их создания и использования.
- •14. Заголовочный файл iomanip. Функции setprecision(), setfill(), setw(). Использование манипуляторов из файла iomanip.
- •Тема 4: Файловый ввод-вывод
- •Понятие файла. Бинарные и текстовые файлы. Преимущества, недостатки, особенности использования.
- •Аргументы командной строки (argc, argv). Обработка данных командной строки. Примеры их использования.
- •Проверка состояния файлового потока. Метод is_open(). Особенности открытия нескольких файлов. Пример их использования.
- •Константы типа seekdir: ios_base::beg, ios_base::cur, ios_base::end. Примеры их использования.
- •Особенности работы с временными файлами. Функция tmpnam_s(). Пример её использования.
- •Класс string. Внутреннее форматирование с использованием классов ostringstream, istringstream. Примеры их использования.
- •Тема 5: Стандартная библиотека шаблонов stl.
- •1. Базовые принципы библиотеки шаблонов stl. Использование библиотеки stl. Заголовочные файлы complex, random.
- •4. Иерархия и концепция итераторов. Необходимость использования каждого типа итераторов. Указатель как итератор. Применение алгоритмов stl к контейнерам, не относящимся к библиотеке stl.
- •5. Входные, выходные, однонаправленные, двунаправленные итераторы, итераторы произвольного доступа: понятие, требования, особенности использования, направленность.
- •6. Шаблонный класс vector, deque, stack. Особенности, методы, принципы работы, возможности
- •7. Шаблонный класс array, valarray. Особенности, методы, принципы работы, возможности
- •8. Шаблонный класс list, forward_list. Особенности, методы, принципы работы, возможности
- •9. Шаблонный класс queue, priority_queue. Особенности, методы, принципы работы, возможности
- •10. Шаблонные классы set и multiset. Особенности, методы, принципы работы, возможности
- •11. Шаблонные классы map и multimap. Особенности, методы, принципы работы, возможности
- •12. Понятие функциональных объектов (функторов). Концепции функторов: генератор, унарная функция, бинарная функция, предикат, бинарный предикат. Предопределенные функторы
- •14. Группы алгоритмов. Алгоритмы «по месту», копирующие алгоритмы. Сравнение функций stl и методов контейнеров stl
- •15. Математические операции и их эквиваленты-функторы. Понятие полного упорядочения и квазиупорядочения
- •17. Понятие обобщенного программирования. Связь обобщенного программирования и библиотеки stl.
- •18. Использование алгоритма copy(), классов ostream_iterator и istream_iterator в качестве моделей входных и входных итераторов
- •19. Итераторы специального назначения: reverse_iterator, back_insert_iterator, front_insert_iterator, insert_iterator
- •Тема 6: Обзор Java. Введение в ооп в Java.
- •2. Обзор и отличительные особенности языка Java. Программная платформа и виртуальная машина Java. Особенности разработки и исполнения объектно-ориентированных приложений на Java.
- •3. Сборка мусора в Java. Пакет jdk: особенности, содержимое, необходимость использования, версии. Ide для работы на Java.
- •4. Особенности настройки работы платформы Java и запуск приложения на языке Java без ide.
- •5. Особенности лексики Java: литералы, идентификаторы, разделители, комментарии, ключевые слова.
- •6. Примитивные типы данных Java. Типизация. Целые числа (byte, short, int, long), числа с плавающей точкой (float, double), символы.
- •7. Переменные. Объявление переменной. Преобразование и приведение типов. Автоматическое приведение и продвижение типов в выражениях. Логические выражения. Область и срок действия переменной.
- •8. Операции (арифметические, поразрядные, отношения, логические (укороченные, обычные)). Операция присваивания. Предшествование операций.
- •9. Управляющие операторы (выбора, цикла, перехода). Разновидность цикла for в стиле for each. Комментарии в Java. Оператор instanceof.
- •Принципы объектно-ориентированного программирования в Java.
Проверка состояния файлового потока. Метод is_open(). Особенности открытия нескольких файлов. Пример их использования.
Новые реализации C++ предлагают способ проверки того, открыт ли файл — метод is_open().
if (!fin.is_open()){ //попытка открытия не удалась
Преимущество этого способа состоит в том, что он проверяет также наличие некоторых незначительных проблем, которые остаются незамеченными другими формами проверки.
В более ранних версиях проверка успешности открытия файла выполнялась следующим образом:
if(fin.fail()) //неудача открытия if(!fin.good()) //неудача открытия if(!fin) //неудача открытия
Объект fin, когда он используется в условии if, преобразуется в false, если fin.good() возвращает false, и в true — в остальных случаях, поэтому две приведенные формы эквивалентны. Однако эти тесты не могут правильно распознать ситуацию, когда предпринимается попытка открытия файла с неподходящим режимом файла. Метод is_open() перехватывает ошибки подобного рода, наряду с теми,которые перехватываются методом good(). Однако в старых реализациях C++ метод is_open() отсутствует.
ОТКРЫТИЕ НЕСКОЛЬКИХ ФАЙЛОВ
Если требуется, чтобы два файла были открыты одновременно, то нужно создать отдельный поток для каждого файла. Например, программа, которая сравнивает два отсортированных файла и отправляет результат в третий, должна создать два объекта ifstream для двух входных файлов и один объект ofstream — для выходного файла. Количество файлов, которые можно открыть одновременно зависит от операционной системы.
Однако можно запланировать последовательную обработку файлов. В этом случае можно открыть единственный поток и по очереди ассоциировать его с каждым из этих файлов.
ifstream fin; //создание потока конструктором по умолчанию fin.open("file1.txt");//ассоциирование потока с файлом file1.txt
//выполнение действий с объектом fin
fin.close(); //разрыв связи потока с файлом file1.txt fin.clear();//сброс fin (может не требоваться)
fin.open("file2.txt");//ассоциирование потока с файлом file2.txt
Режимы открытия файла (ios_base::арр, ios_base::ate, ios_base::binary, ios_base::in, ios_base::out, ios_base::trunc). Метод open(). Связь между режимами открытия файлов языков C++ и С. Добавление данных к содержимому файла. Использование текстового и бинарного файлового ввода-вывода. Примеры их использования.
Режим открытия файла описывает, как файл будет использоваться: для чтения, записи, добавления информации и т.п. При ассоциировании потока с файлом либо инициализацией объекта файлового потока именем файла, либо с помощью метода open(), можно указать второй аргумент, описывающий режим файла:
ifstream fin("file1", ios_base::in);//конструктор с аргументом режима ofstream fout;
fout.open("file2", ios_base::out);//open() с аргументом режима
Класс ios_base определяет тип openmode, представляющий режим взаимодействия с потоком.
Таблица – Режимы открытия файлов C++ и С
Режим C++ |
Режим С |
Описание |
ios_base::in |
"r" |
Открыть для чтения |
ios_base::out |
"w" |
To же, что и ios_base::out | ios_base::trunc |
ios_base::out | ios_base::trunc |
"w" |
Открыть для записи с усечением существующего файла |
ios_base::out | ios_base::app |
"a" |
Открыть для записи с разрешением только на добавление |
ios_base::in | ios_base::out |
"r+" |
Открыть для чтения и записи с разрешением на запись в произвольном месте файла |
ios_base::in | ios_base::out | ios_base::trunc |
"w+" |
Открыть для чтения и записи с усечением существующего файла |
c++mode | ios_base::binary |
"cmodeb" |
Открыть в режиме c++mode или соответствующем режиме cmode и в бинарном (нетекстовом) режиме. Например, ios_base::in | ios_base::binary становится "rb" |
c++mode | ios_base::ate |
"cmode" |
Открыть в указанном режиме и перейти к концу файла. В С вместо кода режима используется |
|
|
отдельный вызов функции. Например, ios_base::in | ios_base::ate преобразуется в режим "r" с последующим вызовом функции fseek(file, 0, SEEK_END) |
ofstream fout("data", ios_base::out | ios_base::app);
Этот код использует операцию | для объединения режимов. Поэтому ios_base::out | ios_base::арр означает, что нужно включить и режим out, и режим арр.
Чтобы сохранить данные в бинарной форме вместо текстовой, можно воспользоваться методом write(). Этот метод копирует указанное количество байт из памяти в файл. Он будет побайтно копировать данные любого типа без каких-либо преобразований. Например, если передать ему адрес переменной типа long и указать, что необходимо скопировать 4 байта, он буквально скопирует в файл 4 байта, составляющие значение типа long, не преобразуя его в текст. Единственной особенностью использования метода write() является то, что необходимо использовать приведение адреса к типу указателя на значение типа char. Тот же подход можно использовать для копирования всей структуры Planet.
Чтобы получить количество байт, которые должны быть записаны, следует применить операцию sizeof:
fout.write((char*)& planet, sizeof planet);
Этот оператор вынуждает программу обратиться к адресу структуры planet и скопировать 40 байт (значение выражения sizeof planet), начиная с указанного адреса, в файл, подключенный к fout.
Чтобы восстановить информацию из файла, нужно использовать соответствующий метод read() с объектом ifstream:
ifstream fin("planets.dat", ios_base::in | ios_base::binary);
fin.read((char*)& planet, sizeof planet);
Последовательный и произвольный доступ. Методы seekg(), seekp(), seekg(), seekp() (перегрузка, особенности использования). Методы tellg(), tellp(). Использование произвольного доступу к содержимому бинарного файла. Примеры использования последовательного и произвольного доступа.
Произвольный доступ (random access) означает возможность произвольного перемещения в любую позицию в файле вместо последовательного перемещения по нему.
чтобы подготовить файл к обработке, нужно использовать следующий оператор:
finout.open(file,ios_base::in|ios_base::out | ios_base::binary);
Далее понадобится способ перемещения по файлу. Класс fstream наследует два предназначенных для этого метода: seekg() перемещает в заданную позицию файла указатель ввода, a seekp() перемещает указатель вывода. На самом деле, поскольку класс fstream использует буферы для промежуточного хранения данных, эти указатели указывают на положение в буферах, а не в реальном файле.
Можно также применять метод seekg() с объектом ifstream, a seekp() — с объектом ofstream.
Методы seekg() и seekp() являются шаблонными. В этой теме используется специализация шаблона для типа char. Для такой специализации приведенные прототипы метода seekg() эквивалентны следующим:
istream& seekg(off_type off, ios_base::seekdir way); istream& seekg(pos_type pos);
ПОВЫШЕНИЕ ТИПА
В более ранних версиях C++ методы seekg() были значительно проще. Типы streamoff и streampos были определены как typedef для некоторого целочисленного типа, такого как long.
следующий оператор устанавливает указатель файла на 112-й байт, который в файле является 113-м байтом:
fin.seekg(112);
Если требуется проверить текущую позицию файлового указателя, то можно воспользоваться методом tellg() для входных потоков и методом tellp() — для выходных.
//Пример №5. Использование произвольного доступу к содержимому бинарного файла
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib> //для exit()
const int LIM = 20; struct planet {
char name[LIM]; //название планеты double population; //население double g; //ускорение свободного падения
};
using namespace std; const char* file = "planets.dat";
inline void eatline() { while (cin.get() != '\n') continue; } int main() { system("chcp 1251"); system("cls"); planet pl; cout << fixed;
//Отображение начального содержимого файла
fstream finout; //потоки чтения и записи
finout.open(file, ios_base::in | ios_base::out | ios_base::binary); int ct = 0; if (finout.is_open()) {
finout.seekg(0); //перейти в начало
cout << "Начальное содержимое файла " << file << " file: \n";
while (finout.read((char*)& pl, sizeof pl)) { cout <<ct++<< " : "<< setw(LIM)<<pl.name << ": " <<setprecision(0)<<setw(12) << pl.population
<<setprecision(2)<< setw(6) << pl.g << endl;
}
if (finout.eof()) finout.clear(); //очистить флаг eof
else {
cerr << "Ошибка чтения данных " << file << ".\n";
exit(EXIT_FAILURE);
}
}
else {
cerr << file << " не может быть открыт!\n"; exit(EXIT_FAILURE);
}
//Изменить запись
cout<<"Введите номер записи, которую вы хотите изменить: "; long rec;
cin >> rec;
eatline(); //избавление от символов новой строки if (rec < 0 || rec >= ct) { cerr << "Неверный номер записи!\n"; exit(EXIT_FAILURE);
}
streampos place = rec * sizeof pl; //преобразование в тип streampos
finout.seekg(place); //произвольный доступ if (finout.fail()) {
cerr << "Ошибка при попытке перемещения по файлу\n"; exit(EXIT_FAILURE);
}
finout.read((char*)& pl, sizeof pl);
cout << "Ваш выбор:\n";
cout << rec << ": " << setw(LIM) << pl.name << ": " << setprecision(0) << setw(12) << pl.population << setprecision(2) << setw(6) << pl.g << endl; if (finout.eof())
finout.clear(); //очистить флаг eof cout << "Введите имя планеты: "; cin.get(pl.name, LIM); eatline();
cout << "Введите количество населения: "; cin >> pl.population;
cout << "Введите ускорения свободного падения: "; cin >> pl.g;
finout.seekp(place); //вернуться назад finout.write((char*)& pl, sizeof pl) << flush; if (finout.fail()) {
cerr << "Ошибка при попытке записи\n"; exit(EXIT_FAILURE);
}
//Отображение измененного файла ct = 0;
finout.seekg(0); //перейти в начало файла cout << "Новое содержимое файла " << file << " :\n";
while (finout.read((char*)& pl, sizeof pl)) { cout << ct++ << ": " << setw(LIM) << pl.name << ": " << setprecision(0) << setw(12) << pl.population
<< setprecision(2) << setw(6) << pl.g << endl;
}
finout.close();
cout << "Программа выполнена успешно.";
return 0;