- •1.1.1 Пример программы, выводящей текст на экран (пример 1)
- •1.1.2 Директивы препроцессору (подключение заголовочных файлов)
- •1.1.3 Комментарии
- •1.1.4 Функции
- •1.1.5 Ввод и вывод на экран
- •1.2. Переменные и их объявление
- •1.2.1 Пример программы cложения целых чисел (пример 2)
- •1.2.2 Переменные и их объявление
- •1.3. Арифметические операторы
- •1.3.1 Примеры арифметических операций (пример 3)
- •1.3.2 Группировка подвыражений с помощью скобок
- •1.4. Логические выражения и оператор if
- •1.4.1 Условные конструкции. Пример условных конструкций (пример 4)
- •1.4.2 Логические выражения. Логические операции и, или, не (пример 5)
- •1.4.3 Типичные ошибки
- •1.4.4 Вложенные условия
- •1.5. Арифметический логический оператор (пример 6)
- •1.6. Селективные конструкции
- •1.6.1 Селективные конструкции. Пример определения оценки в зависимости от количества баллов (пример 6)
- •1.6.2 Оператор Switch. Пример меню с выбором действия (пример 7)
- •1.7. Циклы while и do…while
- •1.7.1 Цикл с предусловием while. Пример возведения в степень в цикле (пример 8)
- •1.7.2 Цикл с постусловием do...While
- •1.8. Пошаговый цикл for
- •1.8.1 Пример работы оператора for - вычисление суммы чисел (пример 9)
- •1.8.2 Пошаговый цикл for
- •1.8.3 Операторы break и continue
- •1.8.4 Пример вычисление факториала (пример 10)
- •1.9. Функции
- •1.9.1 Использование функций библиотеки stl (пример 11)
- •1.9.2 Определение новых функций
- •1.9.3 Пример функции (пример 12)
- •1.10. Размещение программ и данных в памяти
- •1.11. Ссылки и указатели
- •1.11.1. Ссылки
- •1.11.2. Указатели
- •1.11.3. Передача параметров в функцию по ссылке и указателю
- •2.2 Организация ввода/вывода
- •2.3 Строковые переменные и константы
- •2.4 Математические функции
- •3.1. Массивы
- •3.1.1. Одномерный массив
- •3.1.2. Динамическое размещение одномерного массива
- •3.1.3. Передача массива в функцию (пример 3.1)
- •3.1.4. Двумерный массив
- •3.1.5. Динамическое размещение двумерного массива (пример 3.2)
- •3.2 Контейнеры
- •3.3. Вектор vector (пример 3.3)
- •4.4. Список list
- •3.4.1. Списки
- •3.4.2. Итераторы
- •3.4.3. Пример работы со списком с использованием итераторов (пример 3.4)
- •3.5. Очереди и стек
- •3.5.1. Двусторонняя очередь deque (пример 3.5)
- •3.5.2. Стек stack
- •3.5.3. Очередь queue
- •3.6. Ассоциативные контейнеры
- •3.6.1. Контейнер map (пример 3.7)
- •3.6.2. Контейнер set (пример 3.8)
- •3.7. Алгоритмы
- •4.1 Структуры
- •4.1.1. Пример 4.1. Структура для работы с компонентами цвета
- •4.1.2. Передача абстрактных типов в функцию
- •4.1.3. Создание функций-членов для абстрактного типа данных. Пример 4.2. Структура для работы с компонентами цвета со встроенной функцией.
- •4.2. Классы
- •4.2.1. Пример 4.3. Класс Линза
- •4.2.2. Директивы препроцессору # if ! defined, # endif (проверка на повторное подключение)
- •4.2.3. Тип доступа к членам класса
- •4.2.4. Принципы объектно-ориентированного проектирования
- •4.2.5. Типы функций-членов класса
- •4.3 Конструкторы и деструкторы класса
- •4.3.1. Конструкторы
- •4.3.2. Деструктор (пример 4.4. Конструктор и деструктор класса Матрица)
- •4.3.3. Проверка правильности параметров. Исключительные ситуации
- •4.4. Модификаторы, селекторы и другие члены классов
- •4.4.1. Модификаторы и селекторы
- •4.4.2. Ключевые слова const и inline
- •4.4.3. Функции-утилиты
- •4.4.4. Сохраняемость
- •5.1. Типы наследования. Видимость членов классов
- •5.1.1. Наследование
- •5.1.2. Пример 5.1. Линза и зеркало как оптические детали
- •5.1.3. Последовательность вызова конструкторов
- •5.1.4. Типы наследования. Видимость членов классов
- •5.1.5. Множественное наследование
- •5.2. Виртуальные функции. Абстрактные классы
- •5.2.1. Виртуальные функции
- •5.2.2. Абстрактные классы
- •6. Полиморфизм
- •6.1. Перегрузка функций
- •6.1.1. Перегрузка функций
- •6.1.2. Преобразование типов
- •6.1.3. Параметры функций по умолчанию
- •6.2. Перегрузка операторов
- •6.2.1. Пример 6.1 (класс Complex (комплексное число))
- •6.2.6. Перегрузка операторов с присваиванием
- •6.2.7. Перегрузка преобразования типов
- •6.2.8. Перегрузка оператора доступа по индексу
- •6.2.9. Перегрузка операторов ввода/вывода
- •6.2.10. Неперегружаемые операторы
- •6.3. Шаблоны функций и классов
- •6.3.1. Шаблоны функций. Пример 6.2 (шаблон функции)
- •6.3.2. Шаблоны функций с несколькими параметрами. Пример 6.3 (шаблон функции с несколькими параметрами)
- •6.3.3. Шаблоны классов. Пример 6.4 (шаблон класса Комплексное число)
- •6.4. Объекты-функции. Предикаты
- •6.4.1. Объекты-функции. Пример 6.5 (использование объектов-функций)
- •6.4.2. Предикаты. Пример 6.6 (использование предикатов)
4.2.5. Типы функций-членов класса
Поведение описывается набором действий, которые можно совершить над объектом или сам объект может совершить. Что происходит: чтение-запись, выполнение любых вычислений, порождение событий или реакция на те или иные события происходящие в моделируемой системе.
Можно выделить следующие группы действий (функций-членов класса):
конструктор - операция создания объекта и инициализации его атрибутов
деструктор - операция, освобождающая используемые объектом ресурсы и разрушающая его
модификатор - операция, которая изменяет состояние объекта (clear, set_ n, set_ d, …)
селектор - операция, считывающая состояние объекта, но не меняющая ( get_ n, get_ r1, … )
утилита - операция высокого уровня, выполняющая те или иные действия в зависимости от сущности объекта ( Ray Trace, CalcParaxial).
При реализации функций-членов класса, оператор :: показывает принадлежность функции к классу. При реализации всех функций-членов класса к имени функции добавляет <имя класса::>, в нашем случае Lens::. Например:
void Lens::CalculateParaxial()
{
}
4.3 Конструкторы и деструкторы класса
Любой переменной, участвующей в работе программы, требуется память и некоторое начальное значение. Для переменных встроенных типов размещение в памяти обеспечивается компилятором. Для локальных переменных память выделяется из стека программы и занимается для хранения значения данной переменной до тех, пока не закончится время ее жизни. Сложные типы данных также должны размещаться в памяти и уничтожаться когда их время жизни закончилось. Это осуществляется с использованием конструкторов и деструкторов.
Конструктор (constructor) - это функция-член, имя которой совпадает с именем класса, инициализирующая переменные-члены, распределяющая память для их хранения (new).
// конструктор по умолчанию
Lens();
// полный конструктор
Lens(double r1, double r2, double D, double d, double n);
// конструктор копирования
Lens(const Lens& one);
Деструктор (destructor) - это функция-член, имя которой представляет собой ~имя класса, предназначенная для уничтожения переменных (delete).
~Lens(); // деструктор
Одной из особенностей конструктора и деструктора является то, что в отличие от всех остальных функций, у них нет возвращаемого значения.
4.3.1. Конструкторы
Конструктор по умолчанию
Конструктор, не требующий аргументов, называется конструктором по умолчанию. Конструктор по умолчанию не имеет аргументов и инициализирует все переменные члены какими-либо начальными значениями.
// описание конструктора по умолчанию
Lens();
// реализация конструктора по умолчанию
Lens::Lens()
{
m_R1=0.;
m_R2=0.;
m_d=0.;
m_D=0.;
m_n=1.;
}
При создании любого экземпляра класса вызывается конструктор. Если при описании экземпляра не указываются никакие параметры – вызывается конструктор по умолчанию:
// вызов конструктора по умолчанию
Lens test_lens1;
Lens test_lens2();
Lens test_lens3[10][10];
Полный конструктор
Полный конструктор позволяет явно инициализировать все переменные-члены класса.
// описание полного конструктора
Lens(double r1,double r2,double D, double d, double n);
// реализация полного конструктора
Lens::Lens(double r1, double r2, double D, double d, double n)
{
m_R1=r1;
m_R2=r2;
m_d=d;
m_D=D;
m_n=n;
}
Если при описании экземпляра класса в скобках указать параметры, при создании экземпляра класса будет вызван полный конструктор и переменные-члены инициализируются указанными значениями.
// вызов полного конструктора
Lens test_lens(10., -10., 2., 5., 1.5);
Неполный конструктор
Возможен и неполный конструктор, когда в списке параметров указываются не все возможные параметры для инициализации членов класса, а только наиболее часто используемые. Остальные параметры будут инициализированы значениями по умолчанию.
// описание неполного конструктора
Lens(double r1, double r2);
// реализация неполного конструктора
Lens::Lens(double r1, double r2)
{
m_R1=r1;
m_R2=r2;
m_d=0.;
m_D=0.;
m_n=1.;
}
// вызов неполного конструктора
Lens lens(10., -10.);
Инициализация переменных-членов класса в конструкторах может осуществляться не только в теле конструктора, но и после оператора :. При этом, во время присваивания переменной-члену значения, будет вызываться не оператор присваивания, а конструктор. Для встроенных типов данных, таких как double или int, это не существенно, но если членами класса являются абстрактные типы, вызов конструктора вместо оператора присваивания будет выполняться быстрее.
Lens::Lens(double r1, double r2)
: m_R1(R1)
, m_R2(R2)
{
m_d=2.;
m_D=5.;
m_n=1.5;
}
или такой вариант:
Lens::Lens(double R1, double R2)
: m_R1(R1)
, m_R2(R2)
, m_d(2.)
, m_D(5.)
, m_n(1.5)
{
}
Конструктор копирования
Конструктор копирования создает копию уже существующего экземпляра класса, копируя поэлементно переменные-члены. Конструктор копирования также используется при передаче экземпляров класса в функции по значению. Обратите внимание, что экземпляр класса передается в конструктор по константной ссылке.
// описание конструктора копирования
Lens(const Lens& l);
// реализация конструктора копирования
Lens::Lens(const Lens& l)
: m_R1(l.m_R1)
, m_R2(l.m_R2)
, m_d(l.m_d)
, m_D(l.m_D)
, m_n(l.m_n)
{
}
// вызов конструктора копирования
Lens lens1(10., -10.);
Lens lens2(lens1);
