- •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. Классы
В языке С/С++ концепция классов стала расширением понятия структуры, но в отличие от структуры, классы предназначены для выражения не только структуры объекта, но и его поведения. То есть благодаря классам мы можем описать объект (его атрибуты и поведение) на языке программирования и заставить его "жить" в программе. Атрибуты будут описаны на языке в виде переменных-членов класса, а поведение (операции, действия) - в виде функций-членов.
Благодаря этому, при моделировании оптических явлений и процессов, можно в программировании пользоваться теми же понятиями: оптическая поверхность, оптическая среда, линза, диафрагма, предмет, изображение.
На языке С/С++ реализация класса мало чем отличается от реализации структуры, но принято для описания поведения объекта использовать класс, а для хранения разнородных данных (если функции-члены не используются) использовать структуры.
Также как для идентификаторов (переменных) и функций существуют понятия определения, объявления, реализации класса.
Объявление класса - резервирует имя (лексему) как имя класса, нового типа данных.
class Lens;
class Beam;
class Surface;
Объявление класса без его реализации чаще всего используется, когда необходимо использовать тип данных при описании другого класса, но подключение header-файла с полным описанием класса является нерациональным.
Определение класса - языковая конструкция, которая определяет переменные и функции члены класса (их имена, набор аргументов).
Реализация класса – реализация всех функций членов класса.
4.2.1. Пример 4.3. Класс Линза
Рассмотрим пример класса Линза.
/////////////////////////////////////////////////////////////////////////////
// Прикладное программирование
// Пример 4.3. Класс Линза
// lens.h
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// СПб НИУ ИТМО
/////////////////////////////////////////////////////////////////////////////
// проверка на повторное подключение файла
#if !defined LENS_H
#define LENS_H
#include <iostream>
#include "paraxial.h"
/////////////////////////////////////////////////////////////////////////////
// класс ЛИНЗА
class Lens
{
private:
// радиусы кривизны линзы
double m_r1, m_r2;
// диаметр линзы
double m_D;
// осевое расстояние
double m_d;
// показатель преломления
double m_n;
// параксиальные характеристики
Paraxial m_paraxial;
public:
// конструкторы и деструктор
Lens();
Lens(double r1, double r2, double D, double d=0., double n=1.);
Lens(double r1, double r2);
Lens(const Lens& one);
~Lens();
// установка показателя преломления
void Set_n(double n);
// получение показателя преломления
double Get_n() const;
// установка осевого расстояния
void Set_d(double d);
// получение осевого расстояния
double Get_d() const;
// ...
// получение параксиальных характеристик
Paraxial GetParaxial() const;
// запись и чтение
void write(std::ostream& out) const;
void read(std::istream& in);
private:
// вычисление параксиальных характеристик
void CalculateParaxial();
};
/////////////////////////////////////////////////////////////////////////////
// установка показателя преломления
inline void Lens::Set_n(double n)
{
m_n=n;
CalculateParaxial();
}
/////////////////////////////////////////////////////////////////////////////
// получение показателя преломления
inline double Lens::Get_n() const
{
return m_n;
}
/////////////////////////////////////////////////////////////////////////////
// установка осевого расстояния
inline void Lens::Set_d(double d)
{
m_d=d;
CalculateParaxial();
}
/////////////////////////////////////////////////////////////////////////////
// получение осевого расстояния
inline double Lens::Get_d() const
{
return m_d;
}
/////////////////////////////////////////////////////////////////////////////
// получение параксиальных характеристик
inline Paraxial Lens::GetParaxial() const
{
return m_paraxial;
}
/////////////////////////////////////////////////////////////////////////////
#endif //defined LENS_H
/////////////////////////////////////////////////////////////////////////////
// Прикладное программирование
// Пример 4.3. Класс Линза
// paraxial.h
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// СПб НИУ ИТМО
/////////////////////////////////////////////////////////////////////////////
// проверка на повторное подключение файла
#if !defined PARAXIAL_H
#define PARAXIAL_H
#include <iostream>
/////////////////////////////////////////////////////////////////////////////
// структура параксиальных характеристик
struct Paraxial
{
double F, F_; // фокусные расстояния
double SF, SF_; // фокальные отрезки
double SH, SH_; // положения главных плоскостей
Paraxial();
void write(std::ostream& out) const;
};
/////////////////////////////////////////////////////////////////////////////
inline Paraxial::Paraxial()
: F(0)
, F_(0)
, SF(0)
, SF_(0)
, SH(0)
, SH_(0)
{
}
/////////////////////////////////////////////////////////////////////////////
inline void Paraxial::write(std::ostream& out) const
{
out<<"f="<<F<<" f\'="<<F_<<" Sf="<<SF<<" Sf\'="<<SF_<<" SH="<<SH<<" SH\'="<<SH_<<endl;
}
/////////////////////////////////////////////////////////////////////////////
#endif //defined LENS_H
/////////////////////////////////////////////////////////////////////////////
// Прикладное программирование
// Пример 4.3. Класс Линза
// lens.cpp
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// СПб НИУ ИТМО
/////////////////////////////////////////////////////////////////////////////
using namespace std;
// подключение описания класса
#include "lens.h"
/////////////////////////////////////////////////////////////////////////////
// конструктор по умолчанию
Lens::Lens()
: m_r1(0)
, m_r2(0)
, m_d(0)
, m_D(0)
, m_n(1.)
{
CalculateParaxial();
}
/////////////////////////////////////////////////////////////////////////////
// полный конструктор
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)
{
if(n<1)
throw exception("Index of refraction should be greater than 1.");
CalculateParaxial();
}
/////////////////////////////////////////////////////////////////////////////
// неполный конструктор
Lens::Lens(double r1, double r2)
: m_r1(r1), m_r2(r2), m_d(2.), m_D(5.), m_n(1.5)
{
CalculateParaxial();
}
/////////////////////////////////////////////////////////////////////////////
// конструктор копирования
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)
{
CalculateParaxial();
}
/////////////////////////////////////////////////////////////////////////////
// деструктор
Lens::~Lens()
{
}
/////////////////////////////////////////////////////////////////////////////
// запись
void Lens::write(ostream& out) const
{
out<<m_r1<<" "<<m_r2<<" "<<m_d<<" "<<m_D<<" "<<m_n<<endl;
}
/////////////////////////////////////////////////////////////////////////////
// чтение
void Lens::read(istream& in)
{
in>>m_r1>>m_r2>>m_d>>m_D>>m_n;
CalculateParaxial();
}
/////////////////////////////////////////////////////////////////////////////
// вычисление параксиальных характеристик
void Lens::CalculateParaxial()
{
// вычисление параксиальных характеристик
// для проверки задаются значения 100, -100
m_paraxial.F=100.;
m_paraxial.F_=-100.;
//m_paraxial.SF=...
//m_paraxial.SF_=...
//m_paraxial.SH=...
//m_paraxial.SH_=...
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Прикладное программирование
// Пример 4.3. Класс Линза
// test_lens.cpp
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// СПб НИУ ИТМО
/////////////////////////////////////////////////////////////////////////////
#include <iostream>
using namespace std;
// подключение описания класса
#include "lens.h"
/////////////////////////////////////////////////////////////////////
void main()
{
//----------------------------------------------------------------
// тестирование констуркторов класса
// в момент создания экземпляров класса вызывается конструктор по умолчанию
Lens lens1;
Lens lens3[10];
// вызывается полный конструктор
Lens lens4(200., -200., 2., 5., 1.5);
// вызывается неполный конструктор
Lens lens5(100,-100, 66.);
//----------------------------------------------------------------
// тестирование доступа к членам класса
// доступ к членам класса осуществляется по оператору "."
lens5.Set_n(1.6);
// создание указателя на экзепляр класса
Lens* lens6=&lens5;
// если объявлен указатель на экземпляр класса,
// доступ к членам класса осуществляется по оператору "->"
double n=lens6->Get_n();
// вывод на экран значений показателя преломления
// обращение к private членам осуществляется при помощи функций-селекторов
cout<<n<<" "<<lens5.Get_n()<<" "<<lens6->Get_n()<<endl;
// cout<<lens5.m_n; // m_n - private-член (ошибка)
// cout<<lens6->m_n; // m_n - private-член (ошибка)
// cout<<lens6.Get_d(); // lens6 - указатель (ошибка)
// вывод всех параметров линзы на экран
lens5.write(cout);
// вывод на экран параксиальных характеристик линзы
Paraxial parax; // объявление экземпляра параксиальных характеристик
parax=lens4.GetParaxial();
parax.write(cout);
//----------------------------------------------------------------
// в случае возникновения исключительной ситуации внутри блока try
// управление переходит к блоку catch
try
{
Lens lens7(100., -100., 50., 5., 0.);
parax=lens7.GetParaxial();
parax.write(cout);
}
// блок catch - обработка ошибки
catch(exception& error)
{
// вывод на экран сообщения об ошибке
cout<<error.what()<<endl;
}
}
/////////////////////////////////////////////////////////////////////
Разберем подробнее этот пример.
