
- •Лекция 1 Основы алгоритмизации
- •1.1 Языки программирования
- •1.2 Этапы решения задач на компьютере
- •1.3 Понятие алгоритма и его свойства
- •1.4 Графическое описание алгоритмов. Схемы алгоритмов
- •Блоки для изображения схем алгоритмов и программ
- •1.5 Типы алгоритмов
- •Лекция 2 Начальные сведения о языке
- •2.3 Компиляция и выполнение программы
- •Лекция 3 Имена, переменные и константы
- •3.1 Имена
- •3.2 Переменные
- •3.3 Константы
- •Лекция 4 Операции и выражения
- •4.1 Выражения
- •4.2 Операция присваивания
- •4.3.1 Арифметические операции
- •4.3.2 Операции сравнения
- •4.4 Порядок вычисления выражений
- •Лекция 5 Операторы
- •5.1 Что такое оператор
- •5.1.1 Операторы-выражения
- •5.1.2 Объявления имен
- •5.1.3 Операторы управления
- •5.1.3.1 Условные операторы
- •5.1.3.2 Операторы цикла
- •5.1.3.3 Оператор возврата
- •5.1.3.4 Оператор перехода
- •Лекция 6 Функции
- •6.1 Вызов функций
- •6.2 Имена функций
- •6.3 Необязательные аргументы функций
- •6.4 Рекурсия
- •Лекция 7 Встроенные типы данных
- •7.1 Общая информация
- •7.2 Целые числа
- •7.3 Вещественные числа
- •7.4 Логические величины
- •7.5 Символы и байты
- •7.6 Кодировка, многобайтовые символы
- •7.7 Наборы перечисляемых значений
- •Лекция 8 Классы и объекты
- •8.1 Понятие класса
- •8.2 Определение методов класса
- •8.3 Переопределение операций
- •8.4 Подписи методов и необязательные аргументы
- •8.4.1 Запись классов
- •Лекция 9 Производные типы данных
- •9.1 Массивы
- •9.2 Структуры
- •9.2.1 Битовые поля
- •9.3 Объединения
- •9.4 Указатели
- •9.4.1 Адресная арифметика
- •9.4.2 Связь между массивами и указателями
- •9.4.3 Бестиповый указатель
- •9.4.4 Нулевой указатель
- •9.5 Строки и литералы
- •Лекция 10 Распределение памяти
- •10.1 Автоматические переменные
- •10.2 Статические переменные
- •10.3 Динамическое выделение памяти
- •10.4 Выделение памяти под строки
- •10.5 Рекомендации по использованию указателей и динамического распределения памяти
- •10.6 Ссылки
- •10.6 Распределение памяти при передаче аргументов функции
- •10.6.1 Рекомендации по передаче аргументов
- •Лекция 11 Производные классы, наследование
- •11.1 Виртуальные методы
- •11.1.1 Виртуальные методы и переопределение методов
- •11.2 Преобразование базового и производного классов
- •11.3 Внутреннее и защищенное наследование
- •11.4 Абстрактные классы
- •11.5 Множественное наследование
- •11.5.1 Виртуальное наследование
- •15.2 Проблема использования общих функций и имен
- •15.3 Использование включаемых файлов
- •15.4 Препроцессор
- •15.4.1 Определение макросов
- •Условная компиляция
- •15.4.2 Дополнительные директивы препроцессора
- •Лекция 16 Определение, время жизни и области видимости переменных в больших программах
- •16.1 Файлы и переменные
- •16.1.1 Общие данные
- •16.1.2 Глобальные переменные
- •16.1.3 Повышение надежности обращения к общим данным
- •16.2 Область видимости имен
- •16.3 Оператор определения контекста namespace
- •Лекция 17 Обработка ошибок
- •17.1 Виды ошибок
- •17.2 Возвращаемое значение как признак ошибки
- •17.3 Исключительные ситуации
- •17.3.1 Обработка исключительных ситуаций
- •17.3.2 Примеры обработки исключительных ситуаций
- •Лекция 18 Bвод-вывод
- •18.1 Потоки
- •18.3 Манипуляторы и форматирование ввода-вывода
- •18.4 Строковые потоки
- •18.5 Ввод-вывод файлов
- •Лекция 19 Шаблоны
- •19.1 Назначение шаблонов
- •19.2 Функции-шаблоны
- •19.3 Шаблоны классов
- •19.3.1 "Интеллигентный указатель"
- •19.3.2 Задание свойств класса
- •Список использованных источников
- •Содержание
11.5.1 Виртуальное наследование
Базовый класс можно объявить виртуальным базовым классом, используя запись:
class Student : virtual Person
{
};
class Librarian : virtual Person
{
};
Гарантировано, что объект виртуального базового класса будет содержаться в объекте выведенного класса (см. рисунок 11.4) один раз. Платой за виртуальность базового класса являются дополнительные накладные расходы при обращениях к его атрибутам и методам наследования.
Рис.
11.4. Структура объекта StudentLibrarian
при виртуальном множественном
наследовании.
Лекция 12 Контроль доступа к объекту
<В РАЗРАБОТКЕ>
Лекция 13 Классы – конструкторы и деструкторы
<В РАЗРАБОТКЕ>
Лекция 14 Дополнительные возможности классов
<В РАЗРАБОТКЕ>
Лекция 15 Компоновка программ, препроцессор
15.1 Компоновка нескольких файлов в одну программу
Программа – это, прежде всего, текст на языке Си++. С помощью компилятора текст преобразуется в исполняемый файл – форму, позволяющую компьютеру выполнять программу.
Если мы рассмотрим этот процесс чуть более подробно, то выяснится, что обработка исходных файлов происходит в три этапа. Сначала файл обрабатывается препроцессором, который выполняет операторы #include, #define и еще несколько других. После этого программа все еще представлена в виде текстового файла, хотя и измененного по сравнению с первоначальным. Затем, на втором этапе, компилятор создает так называемый объектный файл. Программа уже переведена в машинные инструкции, однако еще не полностью готова к выполнению. В объектном файле имеются ссылки на различные системные функции и на стандартные функции языка Си++. Например, выполнение операции new заключается в вызове определенной системной функции. Даже если в программе явно не упомянута ни одна функция, необходим, по крайней мере, один вызов системной функции – завершение программы и освобождение всех принадлежащих ей ресурсов.
На третьем этапе компиляции к объектному файлу подсоединяются все функции, на которые он ссылается. Функции тоже должны быть скомпилированы, т.е. переведены на машинный язык в форму объектных файлов. Этот процесс называется компоновкой, и как раз его результат и есть исполняемый файл.
Системные функции и стандартные функции языка Си++ заранее откомпилированы и хранятся в виде библиотек. Библиотека – это некий архив объектных модулей, с которым удобно компоновать программу.
Основная цель многоэтапной компиляции программ – возможность компоновать программу из многих файлов. Каждый файл представляет собой законченный фрагмент программы, который может ссылаться на функции, переменные или классы, определенные в других файлах. Компоновка объединяет фрагменты в одну "самодостаточную" программу, которая содержит все необходимое для выполнения.
15.2 Проблема использования общих функций и имен
В языке Си++ существует строгое правило, в соответствии с которым прежде чем использовать в программе имя или идентификатор, его необходимо определить. Рассмотрим для начала функции. Для того чтобы имя функции стало известно программе, его нужно либо объявить, либо определить.
Объявление функции состоит лишь из ее прототипа, т.е. имени, типа результата и списка аргументов. Объявление функции задает ее формат, но не определяет, как она выполняется. Примеры объявлений функций:
double sqrt(double x);// функция sqrt
long fact(long x); // функция fact
// функция PrintBookAnnotation
void PrintBookAnnotation(const Book& book);
Определение функции – это определение того, как функция выполняется. Оно включает в себя тело функции, программу ее выполнения.
// функция вычисления факториала
// целого положительного числа
long fact(long x)
{
if (x == 1)
return 1;
else
return x * fact(x - 1);
}
Определение функции играет роль объявления ее имени, т.е. если в начале файла определена функция fact, в последующем тексте функций и классов ею можно пользоваться. Однако если в программе функция fact используется в нескольких файлах, такое построение программы уже не подходит. В программе должно быть только одно Определение функции.
Удобно было бы поместить Определение функции в отдельный файл, а в других файлах в начале помещать лишь объявление, прототип функции.
// начало файла main.cpp
long fact(long); // прототип функции
int main()
{
. . .
int x10 = fact(10); // вызов функции
. . .
}
// конец файла main.cpp
// начало файла fact.cpp
// определение функции
// вычисления факториала целого
// положительного числа
//
long fact(long x)
{
if (x == 1)
return 1;
else
return x * fact(x - 1);
}
// конец файла fact. cpp
Компоновщик объединит оба файла в одну программу.
Аналогичная ситуация существует и для классов. Любой класс в языке Си++ состоит из двух частей: объявления и определения. В объявлении класса говорится, каков интерфейс класса, какие методы и атрибуты составляют объекты этого класса. Объявление класса состоит из ключевого слова class, за которым следует имя класса, список наследования и затем в фигурных скобках - методы и атрибуты класса. Заканчивается объявление класса точкой с запятой.
class Book : public Item
{
public:
Book();
~Book();
String Title();
String Author();
private:
String title;
String author;
};
Определение класса – это определение всех его методов.
// определение метода Title
String
Book::Title()
{
return title;
}
Определение класса должно быть только одно, и если класс используется во многих файлах, его удобно поместить в отдельный файл. В остальных файлах для того, чтобы использовать класс Book, например определить переменную класса Book, в начале файла необходимо поместить объявление класса.
Таким образом, в начале каждого файла будут сосредоточены прототипы всех используемых функций и объявления всех применяемых классов.
Программа работать будет, однако писать ее не очень удобно.
В начале каждого файла нам придется повторять довольно большие одинаковые куски текста. Помимо того, что это утомительно, очень легко допустить ошибку. Если по каким-то причинам потребуется изменить объявление класса, придется изменять все файлы, в которых он используется. Хотя возможно, что изменение никак не затрагивает интерфейс класса. Например, добавление нового внутреннего атрибута непосредственно не влияет на использование внешних методов и атрибутов этого класса.