- •Определение класса
- •Пример (точка)
- •Оператор вывода (пример)
- •Параметр шаблона по умолчанию (пример)
- •Где перехватывать исключения?
- •Гарантии безопасности исключений
- •Базовые операции
- •Виртуальная функция
- •Использование virtual
- •Массив, как диапазон
- •Контейнер
- •Свойства элемента контейнера
- •Заголовочные файлы
- •Доступ к элементам list
- •Размеры list
- •Доступ к элементам map
- •Очередь с приоритетом
- •Дэк (двусвязная очередь)
- •Матрица (в математике)
- •Атд “матрица”
- •Дерево (доп. Определения)
- •Узел дерева (доп. Определения)
- •“Родственные отношения”
- •“Родственные отношения” (иллюстрация)
- •Баланс в дереве (иллюстрация)
- •Std::less (пример функтора)
- •Std::find_if (пример алгоритма)
- •Функциональные адаптеры
- •Производящая функция
- •Производящие функции для функциональных адаптеров
Оператор вывода (пример)
bool T::writeTxt(ostream& ostr);
ostream&
operator<<(ostream& ostr, T& rhs)
{
rhs.writeTxt(ostr); return ostr;
}
18.02.2012
cppNewb.ru 47
Друзья
функция-член
имеет доступ к закрытой части объявления
находится в области видимости класса
должна вызываться для экземпляров класса
(имеется указатель this)
друг (friend-функция или friend-класс)
имеет доступ к закрытой части объявления
18.02.2012
cppNewb.ru 48
Friend-функция
указывается в объявлении класса,
другом которого она является
может указываться в любой секции
(public, protected, private)
18.02.2012
cppNewb.ru 49
Friend-функция (пример)
class CMatrix;
class CVector
{
friend CVec operator*(const CMatr&, const CVec&);
};
class CMatrix
{
friend CVec operator*(const CMatr&, const CVec&);
};
CVec operator*(const CMatr& lhs, const CVec& rhs)
{
//…
}
18.02.2012
cppNewb.ru 50
Использование друзей
(рекомендации)
друзей использовать не рекомендуется
реализация сильно связных концепций
удовлетворение обоснованных требований по оптимизации
18.02.2012
cppNewb.ru 51
Объектно-ориентированное
программирование
с использованием C++
Полевой Дмитрий Валерьевич к.т.н., доцент КИК
e-mail: oop.misis@gmail.com
Подстановка значений
“волшебные числа”
вычисления на этапе компиляции
подстановка значений (без выделения памяти)
#define MAX_PATH 256
или
const int MAX_PATH(256);
25.02.2012 cppNewb.ru 2
Константность (const)
замена препроцессора
строгий контроль типов
защита данных
оптимизация
25.02.2012 cppNewb.ru 3
Константность и защита данных
инициализация в процессе выполнения
изменение не предусмотрено
компилятор пресекает попытки потенциального изменения (проверка присваиваний)
25.02.2012 cppNewb.ru 4
Указатель (pointer)
тип Т* - тип “указатель на Т”
переменная типа Т* содержит адрес объекта типа Т
разыменование (косвенное обращение)
пример:
char с1 = ‘а’;
char* p = &с1; //< адрес переменной с1 char с2 = *p; //< с2 == ‘а’
25.02.2012 cppNewb.ru 5
Ноль
ноль (0) имеет тип int
константа
арифметический тип
указатель
NULL
использовать запрещено
макрос
25.02.2012 cppNewb.ru 6
Нулевой указатель
гарантируется отсутствие объектов с адресом 0
0 – указатель, который ни на что не ссылается
разыменование нулевого указателя –
ошибка времени исполнения
25.02.2012 cppNewb.ru 7
Массив (встроенный)
составной пользовательский тип
тип T[size] – тип “массив из size
элементов типа Т”
элементы индексируются от 0 до size-1
в памяти расположены подряд
пример:
int divisors[12]; //! не инициализирован
25.02.2012 cppNewb.ru 8
Инициализация встроенного массива
списком инициализаторов
размер массива м.б. вычислен по списку инициализации
не указанные в списке значения инициализируются по умолчанию
используйте T arr[SIZE] = {0};
пример:
int ar1[] = {l, 2, 3, 4}; int ar2[32] = {l, 2};
int ar3[MAX_NUMS] = {0};
25.02.2012 cppNewb.ru 9
Указатели и массивы
имя массива – указатель на первый элемент
доступ через указатели или оператор []
пример:
p = &v[0]; //< или p = v;
v[i] == *(p + i)
25.02.2012 cppNewb.ru 10
Доступ к элементам массива
указатель на массив и индекс
пример:
data[i]
указатель на элемент массива
пример:
*(pData + i)
25.02.2012 cppNewb.ru 11
Арифметика указателей
сложение с целым числом
вычитание целого числа
вычитание указателей
25.02.2012 cppNewb.ru 12
Сложение и вычитание
(целых чисел)
“сдвиг” указателя на заданное число элементов массива
результат разыменования не определен, если адрес вне массива
25.02.2012 cppNewb.ru 13
Вычитание указателей
определено только для указателей на элементы одного массива (язык не позволяет быстро проверить)
число (целое) элементов массива между указателями
25.02.2012 cppNewb.ru 14
Указатель на void
содержит адрес объекта
допустимые операции
присвоение адреса
сравнение на равенство и неравенство
явное преобразование к указателю на другой тип
запрещенные операции
разыменование
арифметические операции
25.02.2012 cppNewb.ru 15
Указатель (в функциях)
параметр
возвращаемое значение
пример:
int* min(const int* pLhs, const int* pRhs)
{
// проверить != 0 для обоих аргументов
return (*pLhs < *pRhs )? pLhs : pRhs;
}
25.02.2012
cppNewb.ru 16
Указатель на константу и константный указатель
указатель на константную переменную
const T* p = 0;
константный указатель
/// д.б. инициализирован
T* const pC = &obj;
константный указатель на константную переменную
/// д.б. инициализирован
const T* const pC = &obj;
25.02.2012 cppNewb.ru 17
Передача и возвращение адресов (указатели и ссылки)
позволяет избежать накладных расходов на копирование
требует дополнительного контроля доступа и изменений
25.02.2012 cppNewb.ru 18
Объект, указатель или ссылка?
если тип не фундаментальный, используйте ссылку или указатель (избегайте лишних объектов)
предпочитайте ссылки
если объекта может не существовать,
используйте указатель
помните о константности
25.02.2012 cppNewb.ru 19
Память (статическая, стек, куча)
статическая память (при компиляции)
глобальные переменные
статические переменные
стек
параметры функций
локальные переменные
куча (heap)
динамическое распределение new/delete
25.02.2012
cppNewb.ru 20
Динамические объекты
время жизни не ограничено областью видимости переменной, а полностью определяется пользователем
“живут” в динамической памяти
25.02.2012 cppNewb.ru 21
Операторы работы с динамическими объектами
оператор new – создает объект
оператор delete – уничтожает объект
указатель, возвращенный new
0 (ноль)
пример:
int* pCounter = new int; //< создадим объект
++(*pCounter);
delete pCounter; //< уничтожим объект
pCounter = 0; //< обнулим для верности
25.02.2012 cppNewb.ru 22
Динамические массивы
new T[SIZE]
delete[]
пример:
/// Cоздадим массив объектов.
int* pCounters = new int[NCOUNTERS];
*(pCounters + 5) += 1;
/// Уничтожим массив.
delete[] pCounters;
pCounters = 0; //< обнулим для верности
25.02.2012 cppNewb.ru 23
Указатель на себя
this – ключевое слово, указатель на текущий экземпляр
определен внутри нестатических методов
нельзя получить адрес
нельзя присвоить значение
используется неявно
25.02.2012
cppNewb.ru 24
Пример неудачный (this)
пример:
void
Point::setX(const int x)
{
}
или
this->m_x = x;
void
Point::setX(const int x)
{
(*this).m_x = x;
}
25.02.2012
cppNewb.ru 25
Пример удачный (this)
T& T::operator++()
{
// содержательная работа
return *this;
}
25.02.2012
cppNewb.ru 26
Использование this
использовать единообразно
избегать избыточности
использовать при необходимости,
т.е. НЕ для доступа к членам в методах
25.02.2012
cppNewb.ru 27
Константные поля
не изменяются после создания объекта
инициализируются в списке инициализации
25.02.2012
cppNewb.ru 28
Константные поля (пример)
class FixedArr
{
public:
FixedArr(int size); private:
const int m_size;
///…
};
FixedArr::FixedArr(int size)
: m_size(size)
///…
25.02.2012
cppNewb.ru 29
Константные методы
сохраняют логическую константность
не изменяют состояния полей кроме
mutable
могут вызываться для константных экземпляров
отличаются от неконстантных методов с тем же набором параметров
25.02.2012
cppNewb.ru 30
Константные методы (пример)
class FixedArr
{
}; int
public:
//…
int size() const;
//…
FixedArr::size() const
{
//…
25.02.2012
cppNewb.ru 31
Члены-ссылки
сильно связанные данные (классы)
инициализируются в списке инициализации
блокируют создание умолчательного конструктора
25.02.2012
cppNewb.ru 32
Ссылочные члены (поля)
class Point
{
public:
Point(Axes& axes); private:
Axes& m_axes;
///…
};
Point::Point(Axes& axes)
: m_axes(axes)
///…
25.02.2012
cppNewb.ru 33
Инвариант класса
“всегда” истинное логическое утверждение (члены)
выполняется в начале и конце метода
может нарушаться внутри метода
25.02.2012
cppNewb.ru 34
Локальная переменная
конструктор вызывается когда управление передается инструкции, содержащей объявление переменной
деструктор вызывается при выходе из
блока, содержащего объявление переменной
25.02.2012
cppNewb.ru 35
Умолчательный конструктор
конструктор без аргументов
генерируется автоматически, если нет объявления других конструкторов
вызывается
создание переменной без использования инициализаторов
создание элемента массива
25.02.2012
cppNewb.ru 36
Копирование объектов
инициализация через копирование
присваивание
передача аргументов и возврат значений
умолчательно является созданием точной бинарной копии
25.02.2012
cppNewb.ru 37
Класс с указателями (пример)
class String
{
public: String()
: m_pStr(new char[SIZE_DEF])
{}
~String()
{
delete[] m_pStr;
}
private:
char m_pStr;
};
25.02.2012
cppNewb.ru 38
Проблемы копирования (пример)
CString str1;
/// Копирующая инициализация – проблема!
CString |
str2 = |
str1; |
CString |
str3; |
|
/// Копирующее присваивание – проблема!
str3 = str1;
25.02.2012
cppNewb.ru 39
Копирование и управление ресурсами
почленное копирование неправильно для классов, реализующих управление ресурсами (конструктор/деструктор)
необходимо использовать пользовательский конструктор копирования и оператор присваивания
25.02.2012
cppNewb.ru 40
Конструктор копирования
T::T(const T&)
генерируется автоматически, если не определен пользователем
м.б. запрещен, определением в private
25.02.2012
cppNewb.ru 41
Конструктор копирования
(пример)
String::String(const String& copy)
: m_pStr(new char[copy.size()])
, m_len(copy.len)
{
memcpy(m_pStr, copy.m_pStr, sizeof(*m_pStr) * size());
}
25.02.2012
cppNewb.ru 42
Оператор присваивания
T& T::operator=(const T&)
генерируется автоматически, если не определен пользователем
м.б. запрещен, определением в private
25.02.2012
cppNewb.ru 43
Схема присваивания (простая)
защита от присваивания самому себе
удаление старых элементов
создание и инициализация
(копирование) новых элементов
существует другая схема (безопасная при исключениях)
25.02.2012
cppNewb.ru 44
Оператор присваивания (пример)
T& T::operator=(const T& copy)
{
// защита от присваивания самому себе
if (this != ©)
{
// копирование
}
return *this;
}
25.02.2012
cppNewb.ru 45
Инициализация и присваивание
копирующий конструктор
инициализирует неинициализированную память
копирующее присваивание
должно обеспечивать правильную работу с уже созданными объектами
избегайте ошибок при попытке уменьшения объема кода
25.02.2012
cppNewb.ru 46
Ошибка генерации автоматического копирования
если нестатический член является
ссылкой
константой
определяемым пользователем типом, не имеющим копирующего оператора присваивания
25.02.2012
cppNewb.ru 47
Структура (struct)
составной пользовательский тип
определяет набор (почти)
произвольных типов
именованный доступ
25.02.2012 cppNewb.ru 48
POD типы
Plain Old Data
объекты можно копировать как фрагменты памяти
25.02.2012
cppNewb.ru 49
Пример структур
пример:
struct Address
{
char[256] m_name; unsigned int m_zip;
};
Adress companyAddress; //! не инициализирован
Adress myAddress = {“D.V. Polevoy”, 156987};
25.02.2012 cppNewb.ru 50
Доступ к членам структур
аналогично классам
. – оператор доступа к члену
-> – оператор разыменования члена структуры (для указателя на структуру)
25.02.2012 cppNewb.ru 51
Перечисление (enum)
пользовательский тип
может иметь собственное имя
определяет набор определяемых пользователем константных значений
приводится к целому в выражениях
25.02.2012 cppNewb.ru 52
Примеры перечислений
enum KeyWord
{
ASM, AUTO, BREAK
};
KeyWord word(ASM);
enum Status
{
OFF, ON,
DISABLE = 255
}
25.02.2012 cppNewb.ru 53
Объектно-ориентированное
программирование
с использованием C++
Полевой Дмитрий Валерьевич к.т.н., доцент КиК
e-mail: oop.misis@gmail.com
Базовые принципы ООП
0. абстракция
инкапсуляция
наследование
полиморфизм
03.03.2012
www.cppNewb.ru 2
Повторное использование кода
уменьшение “стоимости” создания и поддержки ПО
разработка
отладка и тестирование
сопровождение
модификация
эффекты “массовости”
03.03.2012
www.cppNewb.ru 3
Реализация повторного использования кода
модульность – использование готовых компонент (классы, библиотеки)
создание новых классов на основе существующих
инстанциирование (шаблоны)
наследование
03.03.2012
www.cppNewb.ru 4
Проблема повторного использования алгоритмов
один и тот же алгоритм может обрабатывать данные разных типов
пример:
int
minimum(int lhs, int rhs)
{
return (lhs < rhs) ? lhs : rhs;
}
03.03.2012
www.cppNewb.ru 5
Как использовать алгоритм с разными типами?
copy-past
размножение “одинаковых сущностей” и внесение новых ошибок
усложнение поддержки кода
макрос
усложнение отладки и поддержки
пример:
#define min(ls, rs) ((ls < rs) ? ls : rs)
03.03.2012
www.cppNewb.ru 6
Как использовать алгоритм с разными типами?
реализовать шаблонный код
пример: template<class T> T
min(const T& lhs, const T& rhs)
{
return (lhs < rhs) ? lhs : rhs;
}
03.03.2012
www.cppNewb.ru 7
Ключевые слова
template
описание параметризации шаблонна
class и typename
именование параметра
пример:
template<class T>
или
template<typename T>
03.03.2012
www.cppNewb.ru 8
Структура шаблонного кода
template<“параметры”> “объявление”
template<“параметры”>
“определение”
03.03.2012
www.cppNewb.ru 9
Шаблон (template)
в определении (класса или функции) используется один или несколько неизвестных (именованных) типов
типы должны быть известны в момент компиляции программы
03.03.2012
www.cppNewb.ru 10
Преимущества шаблонов
автоматическая генерация кода
оптимизация программ
использование типа при определении
функции или класса
зависит только от тех параметров типа,
которые использует
03.03.2012
www.cppNewb.ru 11
Инстанциирование шаблона
генерация объявления функции (класса) по шаблону функции (класса) и аргументам шаблона
осуществляется компилятором на этапе компиляции
сгенерированный код подчиняется стандартным правилам
03.03.2012
www.cppNewb.ru 12
Шаблонная функция
определяется шаблоном и набором параметров
03.03.2012
www.cppNewb.ru 13
Шаблонный класс (тип)
определяется шаблоном и набором параметров
при использовании одного набора
параметров генерируется один и тот же тип (эквивалентные типы)
03.03.2012
www.cppNewb.ru 14
Шаблонный класс (пример)
template<class T> class CStack
{
public: CStack();
…
T getTop(); private:
T* m_pData;
…
};
03.03.2012
www.cppNewb.ru 15
Параметры шаблонов
тип (типизированный параметр)
константа времени компиляции
(нетипизированный параметр)
другие шаблоны
м.б. несколько
03.03.2012
www.cppNewb.ru 16
Шаблоны членов и методов класса
шаблон класса может иметь шаблонные члены и шаблонные методы
нешаблонный класс может иметь шаблонные методы
03.03.2012
www.cppNewb.ru 17
Нетипизированный параметр
известное на стадии компиляции целочисленное значение (литерал или выражение)
адрес объекта
функция с внешней компоновкой
неперегружаемый указатель на член
03.03.2012
www.cppNewb.ru 18
Нетипизированный параметр
(пример) template<class T, size_t N> class CArr
{
… private:
T m_data[N];
};
CArr<int, 128> members;
03.03.2012
www.cppNewb.ru 19
Типизированный параметр
фундаментальный тип
пользовательский тип
шаблонный тип
03.03.2012
www.cppNewb.ru 20
Типизированный параметр
(пример) template<class T, size_t N> class CArr
{
… private:
T m_data[N];
};
CArr<int, 128> members;
03.03.2012
www.cppNewb.ru 21
Проверка
при определении шаблона
ошибки, которые можно обнаружить вне зависимости от конкретного набора аргументов
при инстанциировании шаблона
ошибки, которые имеют отношение к использованию параметров
03.03.2012
www.cppNewb.ru 22
Слабая типизация
тип обеспечивает интерфейс,
ожидаемый шаблоном
требуется доступность вызываемых функций для типов, параметризующих шаблоны
03.03.2012
www.cppNewb.ru 23
Слабая типизация (пример)
template<typename T> T
min(const T& lhs, const T& rhs)
{
return (lhs < rhs) ? lhs : rhs;
}
03.03.2012
www.cppNewb.ru 24
Параметры шаблона функции
могут быть выведены компилятором, если однозначно определяются списком аргументов
могут быть указаны явно
пример:
int minVal(minimum<int>(a, b));
03.03.2012
www.cppNewb.ru 25
Параметры шаблона класса
должны указываться явно, т.к. никогда не выводятся
пример:
vector<int> marks;
для выведения списка параметров м.б.
использована генерирующая
экземпляры шаблонного класса функция
пример:
make_pair(a, b)
03.03.2012
www.cppNewb.ru 26
Автоматическая генерация экземпляров шаблонного класса
template <class T1, class T2> struct pair ;
template <class T1,class T2> pair<T1,T2>
make_pair(const T1& x, const T2& y)
{
return pair<T1, T2>(x, y);
}
03.03.2012
www.cppNewb.ru 27
Перегрузка функций
можно объявлять
несколько шаблонов с одним именем
комбинацию шаблонов и обычных функций с одним именем
выбор функции
явный квалификатор (параметры шаблона)
разрешение вызова
03.03.2012
www.cppNewb.ru 28
Перегрузка
функций
(пример)
template<typename
T sqrt(T);
T>
template<typename
T>
double sqrt(double);
03.03.2012
www.cppNewb.ru 29