
- •1. Лекция: Начальные сведения о языке
- •2. Лекция: Имена, переменные и константы Имена
- •Переменные
- •Константы
- •3. Лекция: Операции и выражения Выражения
- •Операция присваивания
- •Арифметические операции
- •Операции сравнения
- •Порядок вычисления выражений
- •4. Лекция: Операторы Что такое оператор
- •Операторы-выражения
- •Объявления имен
- •Операторы управления
- •Условные операторы
- •Операторы цикла
- •Оператор возврата
- •Оператор перехода
- •5. Лекция: Функции Вызов функций
- •Имена функций
- •Необязательные аргументы функций
- •Рекурсия
- •6. Лекция: Встроенные типы данных Общая информация
- •Целые числа
- •Вещественные числа
- •Логические величины
- •Символы и байты
- •Кодировка, многобайтовые символы
- •Наборы перечисляемых значений
- •7. Лекция: Классы и объекты Понятие класса
- •Определение методов класса
- •Переопределение операций
- •Подписи методов и необязательные аргументы
- •Запись классов
- •8. Лекция: Производные типы данных Массивы
- •Структуры
- •Битовые поля
- •Объединения
- •Указатели
- •Адресная арифметика
- •Связь между массивами и указателями
- •Безтиповый (нетипизированный) указатель
- •Нулевой указатель
- •Строки и литералы
- •9. Лекция: Распределение памяти Автоматические переменные
- •Статические переменные
- •Динамическое выделение памяти
- •Выделение памяти под строки
- •Рекомендации по использованию указателей и динамического распределения памяти
- •Распределение памяти при передаче аргументов функции
- •Рекомендации по передаче аргументов
- •10. Лекция: Производные классы, наследование
- •Виртуальные методы
- •Виртуальные методы и переопределение методов
- •Преобразование базового и производного классов
- •Внутреннее и защищенное наследование
- •Абстрактные классы
- •Множественное наследование
- •Виртуальное наследование
- •11. Лекция: Контроль доступа к объекту Интерфейс и состояние объекта
- •Объявление friend
- •Использование описателя const
- •Доступ к объекту по чтению и записи
- •12. Лекция: Классы – конструкторы и деструкторы
- •Копирующий конструктор
- •Деструкторы
- •Инициализация объектов
- •Операции new и delete
- •13. Лекция: Дополнительные возможности классов Переопределение операций
- •Как определять операции
- •Преобразования типов
- •Явные преобразования типов
- •Стандартные преобразования типов
- •Преобразования указателей и ссылок
- •Преобразования типов, определенных в программе
- •14. Лекция: Компоновка программ, препроцессор Компоновка нескольких файлов в одну программу
- •Проблема использования общих функций и имен
- •Использование включаемых файлов
- •Препроцессор
- •Определение макросов
- •Условная компиляция
- •Дополнительные директивы препроцессора
- •15. Лекция: Определение, время жизни и области видимости переменных в больших программах Файлы и переменные
- •Общие данные
- •Глобальные переменные
- •Повышение надежности обращения к общим данным
- •Область видимости имен
- •Оператор определения контекста namespace
- •16. Лекция: Обработка ошибок Виды ошибок
- •Возвращаемое значение как признак ошибки
- •Исключительные ситуации
- •Обработка исключительных ситуаций
- •Примеры обработки исключительных ситуаций
- •17. Лекция: Ввод-вывод
- •Манипуляторы и форматирование ввода-вывода
- •Строковые потоки
- •Ввод-вывод файлов
- •18. Лекция: Шаблоны Назначение шаблонов
- •Функции-шаблоны
- •Шаблоны классов
- •"Интеллигентный указатель"
- •Задание свойств класса
Проблема использования общих функций и имен
В языке Си++ существует строгое правило, в соответствии с которым прежде чем использовать в программе имя или идентификатор, его необходимо определить. Рассмотрим для начала функции. Для того чтобы имя функции стало известно программе, его нужно либо объявить, либо определить.
Объявление функции состоит лишь из ее прототипа, т.е. имени, типа результата и списка аргументов. Объявление функции задает ее формат, но не определяет, как она выполняется. Примеры объявлений функций:
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, в начале файла необходимо поместить объявление класса.
Таким образом, в начале каждого файла будут сосредоточены прототипы всех используемых функций и объявления всех применяемых классов.
Программа работать будет, однако писать ее не очень удобно.
В начале каждого файла нам придется повторять довольно большие одинаковые куски текста. Помимо того, что это утомительно, очень легко допустить ошибку. Если по каким-то причинам потребуется изменить объявление класса, придется изменять все файлы, в которых он используется. Хотя возможно, что изменение никак не затрагивает интерфейс класса. Например, добавление нового внутреннего атрибута непосредственно не влияет на использование внешних методов и атрибутов этого класса.