Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции С++.docx
Скачиваний:
4
Добавлен:
22.09.2019
Размер:
6.95 Mб
Скачать

Базовые операции

  • открытие (создание)

  • 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