- •Определение класса
- •Пример (точка)
- •Оператор вывода (пример)
- •Параметр шаблона по умолчанию (пример)
- •Где перехватывать исключения?
- •Гарантии безопасности исключений
- •Базовые операции
- •Виртуальная функция
- •Использование virtual
- •Массив, как диапазон
- •Контейнер
- •Свойства элемента контейнера
- •Заголовочные файлы
- •Доступ к элементам list
- •Размеры list
- •Доступ к элементам map
- •Очередь с приоритетом
- •Дэк (двусвязная очередь)
- •Матрица (в математике)
- •Атд “матрица”
- •Дерево (доп. Определения)
- •Узел дерева (доп. Определения)
- •“Родственные отношения”
- •“Родственные отношения” (иллюстрация)
- •Баланс в дереве (иллюстрация)
- •Std::less (пример функтора)
- •Std::find_if (пример алгоритма)
- •Функциональные адаптеры
- •Производящая функция
- •Производящие функции для функциональных адаптеров
Базовые операции
открытие (создание)
operator<<
запись в поток (поместить данные)
operator>>
чтение из потока (извлечь данные)
|
состояния |
|
24.03.2012 |
(уничтожение)
cppNewb.ru |
34 |
Типы ввода и вывода
форматированный
текстовый
неформатированный
двоичный
24.03.2012 cppNewb.ru 35
Формат
система счисления (oct, dec, hex)
отступы
заполнители
разделители
формат префиксов и суффиксов
разделителя разрядов
и т.д.
24.03.2012 cppNewb.ru 36
Форматирование
формат – состояние потока
(флаги форматирования)
изменение формата
функции
манипуляторы
24.03.2012 cppNewb.ru 37
Форматные флаги (примеры)
ios::showbase
признак системы счисления (dec, oct или hex)
ios::showpoint
десятичная точка и завершающих нулей в вещественных числах
ios::uppercase
верхний регистр букв A-F (hex) и Е (exp)
ios::showpos
отображение знака плюс (+) для положительных величин
24.03.2012 cppNewb.ru 38
Флаги форматирования (функции)
fmtflags flags()
получить текущие флаги
fmtflags flags(fmtflags flNew)
установить флаги
fmtflags |
setf(fmtflags |
flSet) |
fmtflags |
setf(fmtflags |
bits, |
fmtflags field)
добавить флаги
fmtflags unsetf(fmtflags flClear)
снять флаги
24.03.2012 cppNewb.ru 39
Форматное поле
должен быть установлен только один бит из группы
автоматический сброс остальных бит не происходит
используйте перегруженную версию setf
24.03.2012 cppNewb.ru 40
Форматные поля
система счисления целых
ios::basefield
вид чисел с плавающей точкой
ios::floatfield
выравнивание внутри поля
ios::adjustfield
24.03.2012 cppNewb.ru 41
Форматные поля (примеры)
ios::oct
восьмиричные целые
ios::dec
десятичные целые
ios::hex
шестнадцатиричные целые
пример:
s.setf(ios::hex, ios::basefield);
24.03.2012 cppNewb.ru 42
Манипулятор
специальный объект, вызывающий функцию потока
стандартные манипуляторы определены в пространстве имен std
пример:
strm << hex << val << endl;
24.03.2012 cppNewb.ru 43
Цикл работы с форматами
аналогичен работе с ресурсами
запомнить текущее состояние
произвести всю необходимую работу
восстановить исходное состояние
24.03.2012 cppNewb.ru 44
Синтаксис форматированного ввода и вывода
перегруженные операторы двоичного сдвига
cout << “a=” << a;
означает
operator<<(cout, “a=”).operator<<(a);
24.03.2012 cppNewb.ru 45
Ввод и вывод пользовательских типов
ostream& CNum::writeTxt(ostream& ostr)
{
ostr << ‘(’ << m_num << ‘)’; return ostr;
}
ostream& operator<<(ostream& ostr, const CNum& num)
{
return |
num.writeTxt(ostr); |
|
}
24.03.2012 |
cppNewb.ru |
46 |
Построчный ввод
для чтения текстового файла по строкам используйте функцию getline определенную в <string>
пример:
while (0 != getline(file, str).fail())
{
//...
}
24.03.2012 cppNewb.ru 47
Обработка ошибок ввода и вывода
существует состояние потока
текущее состояние зависит от успешности предыдущих операций с потоком
возможность реализации операции с потоком зависит от текущего состояния
24.03.2012 cppNewb.ru 48
Состояние потока (флаги)
ios::badbit
фатальная ошибка, поток использовать нельзя
ios::eofbit
обнаружен конец входных данных (физически достигнут конец файла, пользователь закончил консольный ввод нажатием Ctrl+Z или Ctr+D)
24.03.2012 cppNewb.ru 49
Состояние потока (флаги)
ios::failbit
операция завершилась неудачей (нарушен формат или обнаружен конец данных)
ios::goodbit
ошибок нет, конец данных не обнаружен
24.03.2012 cppNewb.ru 50
Проверка состояния потока
good()
goodbit
eof()
eofbit или badbit
fail()
failbit или badbit
bad()
badbit
24.03.2012 cppNewb.ru 51
Установка состояния потока
clear(iostate _State = goodbit)
сбросить все флаги и установить заданные
setstate(iostate _State)
установить флаги
пример: cout.clear(ios::failbit); cout.setstate(ios::failbit |
~ios::goodbit);
24.03.2012 cppNewb.ru 52
Исключения в потоках
поток может генерировать исключения std::ios_base::failure для заданных флагов состоянии
exceptions
устанавливает статусы
пример:
stmFile.exceptions(ios::badbit);
24.03.2012 cppNewb.ru 53
Неформатированный ввод
чтение отдельного символа или последовательности из потока
get
прочитать из потока отдельный символ
read
прочитать из потока последовательность
24.03.2012
cppNewb.ru 54
Неформатированный вывод
вывод отдельного символа или последовательности в поток
put
записать в поток отдельный символ
write
записать в поток последовательность
24.03.2012
cppNewb.ru 55
Файловые потоки
прикрепляются к объектам файловой системы
ofstream
ifstream
fstream
24.03.2012 cppNewb.ru 56
Цикл работы с файлом
конструктор
open
close
деструктор
пример:
ifstream inData(path);
24.03.2012 cppNewb.ru 57
Режим открытия файла (флаги)
ios::in
чтение (без усечения)
ios::out
запись (без усечения)
ios::app
дописывание
24.03.2012 cppNewb.ru 58
Режим открытия файла (флаги)
ios::ate
существующий файл (чтение, запись в конец)
ios::trunc
существующий файл (запись с начала)
ios::binary
двоичный режим
24.03.2012 cppNewb.ru 59
Файловый поток (пример)
fstream dataFile(path.c_str()
, ios::ate); dataFile << obj1; dataFile << obj2; dataFile.close();
…
dataFile.open(path.c_str(), ios::in);
…
24.03.2012 cppNewb.ru 60
Позиционирование в потоке
tellp
получить позицию записи
tellg
получить позицию чтения
seekp
установить позицию записи
seekg
установить позицию чтения
24.03.2012 cppNewb.ru 61
Относительное позиционирование
ios::beg
от начала
ios:cur
от текущей позиции
ios::end
от конца
24.03.2012 cppNewb.ru 62
Буферизация
для записи и чтения используется буфер, который освобождается при переполнении или по требованию
пример:
strm.flush();
strm << obj << endl;
24.03.2012 cppNewb.ru 63
Строковые потоки
прикрепляются к строковым объектам
ostringstream
istringstream
stringstream
str()
получение буфера std::string
24.03.2012 cppNewb.ru 64
Строковый поток (пример)
ostringstream strm(strBuf); strm << “Formated text\n”;
...
istringstream strm(strBuf);
strm >> obj;
...
24.03.2012 cppNewb.ru 65
Объектно-ориентированное
программирование
с использованием C++
Полевой Дмитрий Валерьевич к.т.н., доцент КиК
e-mail: oop.misis@gmail.com
extern (ключевое слово)
объявление
функции
переменной
пример:
// в a.cpp
int gObjectsCounter(0);
// в b.cpp
extern int gObjectsCounter;
31.03.2012
cppNewb.ru 2
static (ключевое слово)
глобальная статическая переменная
область видимости ограничивается единицей трансляции
локальная статическая переменная
значение сохраняется между вызовами
31.03.2012
cppNewb.ru 3
Статическая переменная
(пример)
// в point.cpp
static gModuleCallsCount(0);
int inside(const Pt& p, const Rect& rc)
{
static nFuncCallsCount(0); nFuncCallsCount += 1; gModuleCallsCount += 1; // плохо
...
}
31.03.2012
cppNewb.ru 4
Статический член класса
является частью класса, но не экземпляра
д.б. где-то определен
31.03.2012
cppNewb.ru 5
Статический член класса
(пример)
пример:
// в point.h class Point
{
public:
-
static
int
getRefPoint();
private:
static
int
m_xRefPoint;
};
// в point.cpp
int CPoint::m_xRefPoint = 0;
31.03.2012
cppNewb.ru 6
Доступ к статическому члену класса
через экземпляр CPoint point; point.getRefPoint();
через имя класса
CPoint::getRefPoint();
31.03.2012
cppNewb.ru 7
Реализация повторного использования кода
создание новых классов на основе существующих
агрегация (готовых компонент)
наследование
31.03.2012 cppNewb.ru 8
Идея
программа моделирует реальность
классы моделируют концепции реального и программного мира
существуют отношения концепций
язык С++ поддерживает моделирование концепций и некоторых типов отношений с помощью пользовательских типов
31.03.2012 cppNewb.ru 9
Композиция (отношение)
способ создания новых классов
новый класс включает поля существующих типов (классов)
31.03.2012 cppNewb.ru 10
Композиция (пример)
class Man
{
… private:
string m_name; string m_secName;
};
class CStudent
{
… private:
Man m_man; Group m_group;
};
31.03.2012 cppNewb.ru 11
Наследование (отношение)
способ создания новых классов
позволяет явно отражать общность
классов (новый класс наследует члены)
31.03.2012 cppNewb.ru 12
Понятия иерархии наследования
базовый (родительский) класс
производный (дочерний) класс
31.03.2012 cppNewb.ru 13
Наследование (пример)
class Man
{
… private:
string m_name; string m_secName;
};
class CStudent
: public Man
{
… private:
Group m_group;
};
31.03.2012
cppNewb.ru 14
Синтаксис наследования
сlass Derived
:[private|protected|public] Base
{
// class body
};
31.03.2012 cppNewb.ru 15
Умолчательный спецификатор типа наследования
private для классов
public для структур
спецификатор рекомендуется указывать явно
пример:
class Derived
: public Base
{ …
};
31.03.2012 cppNewb.ru 16
Иерархии понятий
данные
ответственности (интерфейсы)
31.03.2012 cppNewb.ru 17
Повышающее преобразование
при обращении через указатель или ссылку с экземпляром производного класса можно обращаться как с экземпляром базового класса
повышающее приведение типа
приведение указателя (ссылки) производного типа к указателю (ссылке) базового типа
31.03.2012 cppNewb.ru 18
Повышающее преобразование
(пример)
// class Student : public Man class Student student;
class Man* pMan = &student;
…
pMan->name();
…
Student является Man, поэтому Student*
можно использовать как Man*
31.03.2012 cppNewb.ru 19
Повышающее преобразование
(пример)
// class Student : public Man void printInfo(ostream& ostr,
Man& man);
…
Student me;
…
printInfo(cout, me);
…
31.03.2012 cppNewb.ru 20
Подстановочный критерий
(нестрогая формулировка)
в любой точке вызова базового класса м.б. использован производный класс
или
любой экземпляр производного класса является допустимым экземпляром родительского класса
31.03.2012 cppNewb.ru 21
Конструирование производных объектов
конструктор базового класса д.б. вызван
умолчательные конструкторы базовых
классов м.б. вызваны неявно компилятором
31.03.2012 cppNewb.ru 22
Список инициализации (пример)
Student::Student(
-
const
string&
name
,
const
string&
secname
, const Group& group)
: Man(name, secname)
, m_group(group)
{
}
31.03.2012 cppNewb.ru 23
Конструктор производного класса
должен
инициализировать базовый класс
инициализировать собственные поля
непосредственная инициализация
полей базового класса невозможна
31.03.2012 cppNewb.ru 24
Порядок вызова конструкторов
по всей цепочке иерархии наследования, начиная от корневого базового класса и до текущего
на каждом уровне вызывается
конструктор базового класса
конструкторы внутренних объектов
31.03.2012 cppNewb.ru 25
Деструктор
каждый класс содержит единственный деструктор (без аргументов)
компилятор гарантирует вызов всех
деструкторов (по всей иерархии наследования)
31.03.2012 cppNewb.ru 26
Порядок вызова деструкторов
обратный порядку вызова конструкторов
по всей цепочке иерархии
наследования, начиная от текущего и до корневого базового класса
на каждом уровне вызывается
деструкторы внутренних объектов
деструктор базового класса
31.03.2012 cppNewb.ru 27
Замещение метода
в производном классе м.б. определен метод с именем метода базового класса
переопределение перегруженного имени функции базового класса скрывает все остальные версии в производном классе
31.03.2012 cppNewb.ru 28
Изменение интерфейса
(в т.ч. замещение)
изменение интерфейса базового класса посредством модификации сигнатуры и/или типа возвращаемого значения означает, что класс используется не
тем способом, для которого обычно
предназначается наследование
31.03.2012 cppNewb.ru 29
Доступ к скрытым именам
осуществляется через полное имя
пример:
void
Derived::print(ostream& ostr)
{
Base::print(ostr);
…
}
31.03.2012 cppNewb.ru 30
Функции, которые не наследуются
конструкторы и деструкторы
operator=
31.03.2012 cppNewb.ru 31
Конструктор копирования при наследовании (пример)
Der::Der(const Der& copy)
: Base(copy)
// инициализация полей экземпляра
{
// дополнительная работа
// конструктора
}
31.03.2012 cppNewb.ru 32
Оператор присваивания при наследовании (пример)
Der&
Der::operator=(const Der& copy)
{
CBase::operator=(copy);
// остальная работа оператора
}
31.03.2012 cppNewb.ru 33
Статические функции
(при наследовании)
наследуются производными классами
переопределение скрывает все остальные перегруженные версии в базовом классе
т.е. аналогично обычным функциям
31.03.2012 cppNewb.ru 34
Выбор между композицией и наследованием
композиция (b содержит a)
отношение “has-a”
повторное использование кода
наследование (b является a)
отношение “is-a”
повторное использование интерфейса
31.03.2012 cppNewb.ru 35
Закрытое наследование
лучше использовать композицию
реализует “ограниченную реализацию”
пользователь не имеет доступа к
базовой функциональности
экземпляр производного класса не может интерпретироваться как экземпляр базового класса
31.03.2012 cppNewb.ru 36
Закрытое наследование (пример)
// in base.h
class Base
{
public:
int aF();
int aF(int a); void bF();
…
// in der.h
class Der
: private CBase
{
using CBase::aF; using CBase::bF;
…
};
};
31.03.2012 cppNewb.ru 37
Защищенность
ключевое слово protected
защищенный член ведет себя как
открытый для членов производных классов
закрытый для всех остальных функций
31.03.2012 cppNewb.ru 38
Защищенное наследование
реализует
открытую реализацию для производных и дружественных классов
“ограниченную реализацию” для других классов
на практике используется редко
Матрица доступа
|
методы и друзья класса |
методы и друзья
производных |
пользов атели |
public |
есть |
есть |
есть |
protected |
есть |
есть |
нет |
private |
есть |
нет |
нет |
Рекомендации
делайте все данные private,
обеспечивая доступ к ним через методы
используйте protected для методов реализации, которые могут использоваться в производных классах
Полиморфизм
полиморфный – “имеющий много форм”
взаимозаменяемость объектов с одинаковым интерфейсом
использование одного имени для разных задач (реализаций)
31.03.2012 cppNewb.ru 42
Виды наследования
одиночное наследование
один непосредственный базовый класс
множественное наследование
более одного непосредственного базового класса
31.03.2012
cppNewb.ru 43
Множественное наследование
(синтаксис)
в списке базовых классов через запятую указываются все базовые классы (непосредственные)
пример:
class Derived
: public Base1
, public Base2
{
...
31.03.2012
cppNewb.ru 44
Проблемы множественного наследования
неоднозначности имен (членов и методов)
повторяющиеся базовые классы
(ромбовидная схема наследования)
размещение данных в памяти
порядок и количество вызовов методов
31.03.2012
cppNewb.ru 45
Использование множественного наследования
избегайте без наличия весомой причины и полного понимания работы механизмов языка
используйте для наследования нескольких интерфейсов
31.03.2012
cppNewb.ru 46
Объектно-ориентированное
программирование
с использованием C++
Полевой Дмитрий Валерьевич к.т.н., доцент КиК
e-mail: oop.misis@gmail.com
Тип и класс
тип определяется интерфейсом, т.е.
набором допустимых операций
класс реализует один или несколько типов
интерфейс класса м.б. шире, чем интерфейс типа
07.04.2012 cppNewb.ru 2
Повышающее приведение типа
интерпретация адреса экземпляра производного класса в качестве адреса экземпляра базового класса
(через указатель или ссылку)
“сужает” интерфейс производного класса до интерфейса базового
допустимо при соблюдении подстановочного принципа
07.04.2012 cppNewb.ru 3
Повышающее приведение типа
(пример)
//class CStudent : public CMan
void
protocol(ostream& os, const CMan& man)
{
printHeader(os); man.writeTxt(os); printFooter(os);
}
07.04.2012 cppNewb.ru 4
Связывание
соотнесение вызова функции с телом функции
раннее связывание
реализуется компилятором и компоновщиком до запуска программы (при “сборке”)
позднее (динамическое) связывание
осуществляется в процессе исполнения программы в зависимости от фактического типа экземпляра
07.04.2012 cppNewb.ru 5