SlideShare une entreprise Scribd logo
1  sur  76
Télécharger pour lire hors ligne
Углубленное программирование
на языке C++
Алексей Петров
Обзор курса (1 / 3)
Модуль №1. Объектная модель языка С++. Безопасное
программирование
• Лекция №1. Цели и задачи курса. Специальные вопросы
инкапсуляции
• Лекция №2. Специальные вопросы наследования и полиморфизма.
Множественное и виртуальное наследование. Динамическая
идентификация типов (RTTI)
• Лекция №3. Шаблоны классов и методов. Обработка
исключительных ситуаций. Обобщенное и безопасное
программирование
• Практикум №1 / 2. Проектирование / разработка полиморфной
иерархии классов повышенного уровня сложности
Обзор курса (2 / 3)
Модуль №2. Библиотеки для промышленной разработки ПО:
STL, Boost
• Лекция №4. Введение в STL
• Лекция №5. Реализация STL. Элементы функционального
программирования
• Лекция №6. Практическое введение в Boost
• Практикум №3. Разработка и обеспечение безопасности
полиморфной иерархии с шаблонами классов
• Практикум №4. Оптимизация полиморфной иерархии классов с
использованием элементов библиотек STL и Boost
Обзор курса (3 / 3)
Модуль №3. Шаблоны объектно-ориентированного
проектирования. Основы промышленной разработки ПО
• Лекция №7. Принципы и шаблоны объектно-ориентированного
проектирования. Базовые и порождающие шаблоны
• Лекция №8. Основные шаблоны проектирования однопоточных
приложений. Структурные и поведенческие шаблоны
• Лекция №9. Идиоматика C++. Основы рефакторинга и оптимизации
исходного кода
• Лекция №10. Качество исходного кода. Стандарты кодирования и
основы командной разработки ПО
• Практикум №5. Оптимизация полиморфной иерархии классов с
использованием шаблонов объектно-ориентированного
проектирования однопоточных приложений
• Практикум №6. Рефакторинг и документирование объектно-
ориентированного исходного кода
Лекция №1. Цели и задачи курса.
Специальные вопросы
инкапсуляции
• Цели, задачи, структура курса.
• Определение и состав класса.
• Работа с членами класса и указателями на них.
• Дружественные классы и функции.
• Вложенные типы.
• Инициализация, копирование, преобразование и уничтожение
объектов.
• Инкапсуляция и вопросы производительности.
• Постановка задач к практикуму №1.
Цель и структура курса
Цель курса — сформировать практические навыки и умения,
необходимые специалистам по разработке программного обеспечения
(ПО) для участия в проектах промышленной разработки среднего
уровня сложности.
Состав курса — 10 лекций, 6 практикумов:
• осень 2012 (для сравнения) — 12 лекций, 4 практикума.
Общая аудиторная нагрузка — 64 акад. часа:
• лекционные занятия — 40 акад. часов;
• практические работы — 24 акад. часа.
Чему научимся?
Практический результат (1 / 2)
Обязательно:
• моделировать систему при помощи UML-диаграмм классов;
• разрабатывать код на языке C++;
• использовать приемы обобщенного и безопасного
программирования;
• применять промышленные библиотеки STL, Boost;
• внедрять в продукт классические архитектурные шаблоны GoF;
• оценивать качество и выполнять рефакторинг исходного
программного кода;
• презентовать и защищать свои разработки перед аудиторией.
Чему научимся?
Практический результат (2 / 2)
По желанию:
• моделировать варианты использования продукта;
• выполнять кодогенерацию по UML-моделям;
• использовать новые возможности языка C++11;
• писать многопоточные приложения;
• реализовывать графический интерфейс пользователя в Qt.
Организационные
положения
Расписание занятий:
• постановка задач к практикумам — на лекциях №№1, 2, 3, 5, 7 и 9
(работа выполняется в командах!).
Регламент занятия:
• продолжительность — 4 акад. часа с 1 или 2 перерывами общей
продолжительностью до 10 минут;
• вопросы — общезначимые: в любое время (во время пауз или по
поднятию руки!), индивидуальные: в перерыве или после занятия;
• ведение видеосъемки (задавайте вопросы по существу и
разборчиво!).
Знакомство с аудиторией:
• известные языки программирования (C, C++, Java);
• опыт разработки, известные среды и технологии.
Рекомендуемая
литература (1 / 3)
• Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. Приемы объектно-
ориентированного проектирования. Паттерны проектирования. —
Питер, 2007. — 366 с.
• Кериевски Дж. Рефакторинг с использованием шаблонов. —
Вильямс, 2006. — 400 с.
• Липпман С., Лажойе Ж. Язык программирования C++. Вводный
курс. — Невский Диалект, ДМК Пресс. — 1104 с.
• Липпман С., Лажойе Ж., Му Б. Язык программирования C++.
Вводный курс. —Вильямс, 2007. — 4-е изд. — 896 с.
• Лишнер Р. STL. Карманный справочник. — Питер, 2005. — 188 с.
• Макконнелл С. Совершенный код. Мастер-класс. — Русская
редакция, 2012. — 896 с.
Рекомендуемая
литература (2 / 3)
• Мюссер Д., Дердж Ж., Сейни А. C++ и STL. Справочное руководство.
— Вильямс, 2010. — 432 с.
• Саттер Г. Новые сложные задачи на C++. — Вильямс, 2005. — 272 с.
• Саттер Г. Решение сложных задач на C++. — Вильямс, 2008. —
400 с.
• Саттер Г., Александреску А. Стандарты программирования на C++.
— Вильямс, 2008. — 224 с.
• Седжвик Р. Алгоритмы на C++. — Вильямс, 2011. — 1056 с.
• Страуструп Б. Программирование. Принципы и практика
использования C++. — Вильямс, 2011. — 1248 с.
• Страуструп Б. Язык программирования C++. — Бином, 2011. —
1136 с.
Рекомендуемая
литература (3 / 3)
• Фаулер М. Рефакторинг. Улучшение существующего кода. —
Символ-Плюс, 2008. — 432 с.
• Шилдт Г. Полный справочник по C++. — Вильямс, 2007. — 800 с.
• Demming, R., Duffy, D.J. Introduction to the Boost C++ Libraries; Volume
I – Foundations (Datasim Education BV, 2010).
• Demming, R., Duffy, D.J. Introduction to the Boost C++ Libraries; Volume
II – Advanced Libraries (Datasim Education BV, 2012).
• Musser, D.R., Saini, A. STL Tutorial and Reference Guide: C++
Programming with the Standard Template Library (Addison-Wesley,
1995).
• Schäling, B. The Boost C++ Libraries. URL:
http://en.highscore.de/cpp/boost/.
• Standard Template Library Programmer’s Guide. URL:
http://www.sgi.com/tech/stl/
Web-ресурсы
• Официальный Web-сайт проекта Boost: http://www.boost.org/.
• Официальный Web-сайт проекта Eclipse: http://www.eclipse.org/.
• Справка по языкам C / C++: http://ru.cppreference.com/w/,
http://en.cppreference.com/w/.
Дискуссия
Объектно-ориентированное программирование — это…
Инкапсуляция —
базовый принцип ООП
Инкапсуляция, или сокрытие реализации, является фундаментом
объектного подхода к разработке ПО.
Следуя данному подходу, программист рассматривает задачу в
терминах предметной области, а создаваемый им продукт видит как
совокупность абстрактных сущностей — классов (в свою очередь
формально являющихся пользовательскими типами).
Инкапсуляция предотвращает прямой доступ к внутреннему
представлению класса из других классов и функций программы.
Без нее теряют смысл остальные основополагающие принципы
объектно-ориентированного программирования (ООП): наследование и
полиморфизм. Сущность инкапсуляции можно отразить формулой:
Открытый интерфейс + скрытая реализация
Класс: в узком или широком
смысле?
Принцип инкапсуляции распространяется не только на классы
(class), но и на структуры (struct), а также объединения (union). Это
связано с расширительным толкованием понятия «класс» в стандарте
языка C++. Понятие «класс» в языке C++ может трактоваться в узком
или широком смысле.
Класс в узком смысле — одноименный составной пользовательский
тип данных, являющийся контейнером для данных и алгоритмов их
обработки. Вводится в текст программы определением типа со
спецификатором class.
Класс в широком смысле — любой составной пользовательский тип
данных, агрегирующий данные и алгоритмы их обработки. Вводится в
текст программы определением типа с одним из спецификаторов
struct, union или class.
Определение класса (1 / 2)
Простейшее определение класса в языке C++ имеет вид:
// заголовок класса
<спецификатор класса> <имя класса>
{ // тело класса
[<члены класса>]
};
где <спецификатор класса> — ключевое слово class, union или
struct, <имя класса> — правильный идентификатор, а <члены
класса> определены в соответствии с требуемым уровнем доступа
(открытые, закрытые, защищенные).
Каждое определение класса вводит новый тип данных.
Тело класса определяет полный перечень его членов, который не
может быть расширен после закрытия тела.
Определение класса (2 / 2)
Например:
// пустой класс
class Document { };
// непустой класс
class Book {
public:
Book();
private:
string _author, _title;
};
Объявление класса (1 / 2)
Объявление класса вида
<спецификатор класса> <имя класса>;
вводит в программу имя класса и указывает его природу, не определяя
состав атрибутов, методов и иных составных частей класса.
В случае если класс объявлен, но не определен, допускается:
• определять ссылки и указатели на объект класса;
• определять член другого класса как ссылку или указатель на данный
класс.
В случае если класс объявлен, но не определен, запрещается:
• определять объект класса;
• определять член другого класса как принадлежащий данному
классу;
• разыменовывать указатели на объект класса;
• использовать ссылки и указатели для доступа к членам класса.
Объявление класса (2 / 2)
Например:
// объявление класса
class Account; // можно
// определения объектов
class Account acc; // нельзя
Account *pAcc = NULL; // можно
void foo(const Account *pA); // ???
Объект класса (1 / 2)
Выделение памяти под объект класса происходит при определении
такого объекта, ссылки на объект или указателя на него.
Объект класса имеет размер, достаточный для размещения в нем всех
(нестатических) атрибутов, собственную копию каждого из которых
имеет каждый индивидуальный объект.
Объект класса характеризуется областью видимости и обладает
временем жизни.
Объекты одного класса могут присваиваться друг другу. В отсутствие
в определении класса специального метода (конструктора
копирования) копирование объектов эквивалентно побайтовому
копированию каждого атрибута.
Будучи параметром или возвращаемым значением функции, объект
класса передается по значению.
Объект класса (2 / 2)
Например:
// определение класса
class Account { /* … */ };
class Deposit { /* … */ } deposit;
// определения объектов: правильно
class Account acc;
Account *pAcc = new Account(100);
Account &rAcc = acc;
// определения объектов: ???
class Account *&prAcc = pAcc;
Account &rAcc2 = &acc;
Константный объект
класса (1 / 2)
Объект класса (как и объект базового типа) может быть объявлен
константным. Константный объект не допускает изменения значения
его атрибутов на протяжении всего времени жизни объекта, за
исключением
• времени работы конструктора (объект создается);
• времени работы деструктора (объект уничтожается).
Константный объект
класса (2 / 2)
Неизменность членов-данных, являющихся указателями,
распространяется только на их значение (адрес) и не
распространяется на содержимое областей памяти, которые они
адресуют.
Примечание: Модификация адресуемых таким образом областей
памяти демонстрирует «плохой стиль» программирования.
Например:
const Document myDocument;
Состав класса (1 / 2)
В состав класса на языке C++ могут входить следующие элементы
(начало):
• атрибуты (данные-члены — содержательная сторона класса):
• статические (со спецификатором static), в том числе
константные (со спецификатором const);
• неустойчивые (со спецификатором volatile);
• изменчивые (со спецификатором mutable);
• прочие (без формальных спецификаторов);
• методы (функции-члены — алгоритмическая сторона класса), в том
числе специальные (конструкторы, деструкторы):
• встроенные (со спецификатором inline);
• константные (со спецификатором const);
• статические (со спецификатором static);
• неустойчивые (со спецификатором volatile);
• прочие (без формальных спецификаторов);
Состав класса (2 / 2)
В состав класса на языке C++ могут входить следующие элементы
(окончание):
• описания дружественных объектов:
• прототипы дружественных функций;
• описания дружественных классов;
• определения типов;
• битовые поля;
• вложенные классы.
Нестатические члены
данных (1 / 2)
За содержательную сторону реализованной в виде класса абстракции
предметной области отвечают данные-члены, или атрибуты, класса.
Чаще всего каждый экземпляр (объект) класса имеет собственный
набор атрибутов. Назовем такие атрибуты класса нестатическими.
Нестатические члены данных сопоставляются с конкретным
экземпляром класса и тиражируются. Время жизни такого члена
данных равно времени жизни объекта.
Нестатические члены данных нельзя инициализировать в теле класса.
Для обращения к нестатическим членам данных служат операции
доступа (. или ->), левым операндом которых выступает
леводопустимое выражение: идентификатор объекта, ссылка или
указатель на объект (допустимый вариант — this, см. далее).
Нестатические члены
данных (2 / 2)
Например:
class Book
{ /* … */
int _pages;
string _title;
vector<string> _chapTitles;
/* … */
} book;
Book *pBook = &book;
/* … */
book._pages = 100;
// pBook->_pages = 100; (*pBook)._pages = 100;
Статические члены
данных (1 / 3)
Статический член данных класса — это глобальный объект,
совместно используемый всеми объектами своего класса.
Статические объекты не тиражируются и существуют даже при
отсутствии экземпляров, поскольку связаны не с переменной
(объектом), а типом (классом).
Преимущества статических членов данных перед глобальными
объектами состоят в том, что:
• статические члены находятся в области видимости класса, а не в
глобальном пространстве имен;
• на статические члены распространяется действие спецификаторов
доступа.
Статические члены
данных (2 / 3)
В общем случае статический член инициализируется вне определения
класса. Определение статического члена данных в программе может
быть лишь одно.
Примечание: В качестве исключения константный статический член
целого типа может быть проинициализирован константой внутри тела
класса. В этом случае он трактуется как константное выражение
(именованная константа).
Для обращения к статическому члену класса может использоваться
операция доступа с леводопустимым выражением или операция
разрешения области видимости с именем класса в качестве левого
операнда.
Статический член данных может иметь тот же тип класса, членом
которого он является, а также быть аргументом по умолчанию для
метода класса.
Статические члены
данных (3 / 3)
Например:
class BinaryTree
{ /* … */
static char delimiter;
static const short base = 10;
static const char *_format;
};
char BinaryTree::delimiter = ',';
const char *BinaryTree::_format = "(%d) %d,_";
BinaryTree tree; /* … */
tree.delimiter = ' ';
BinaryTree::delimiter = ';';
Неустойчивые объекты (1 / 2)
Неустойчивые, или асинхронно изменяемые (volatile), объекты могут
изменяться незаметно для компилятора.
Пример: переменная, обновляемая значением системных часов или
значением, полученным через системный порт.
Целью определения объекта как неустойчивого является
информирование компилятора о том, что тот не может определить,
каким образом может изменяться значение данного объекта.
Спецификатор volatile сообщает компилятору о том, что при работе с
данным объектом не следует выполнять оптимизацию кода.
Неустойчивые объекты (2 / 2)
Допустимы неустойчивые объекты скалярных и составных типов,
указатели на неустойчивые объекты, неустойчивые массивы:
• в неустойчивом массиве неустойчивым считается каждый элемент;
• в неустойчивом экземпляре (объекте) класса неустойчивым
считается каждый член данных. Объекты классов неустойчивы
целиком.
Например:
// неустойчивый скаляр
volatile unsigned long timer;
// неустойчивый массив
volatile short ports[size];
// указатель на неустойчивый объект класса
volatile Timer *tmr;
Для преобразования неустойчивого типа в устойчивый используется
const_cast.
Изменчивые члены данных
Атрибуты класса, допускающие модификацию при любом
использовании объекта, должны определяться как изменчивые.
Изменчивые атрибуты не являются константными, даже будучи
членами константного объекта, что позволяет модифицировать их
значения, в том числе константными методами.
Например:
class Book
{ /* … */
mutable int _currentPage;
/* … */
void locate(const int &value) const
{ /* … */_currentPage = value; /* … */ }
};
Указатель this
Указатель this — неявно определяемый константный указатель на
объект класса, через который происходит вызов соответствующего
нестатического метода.
Для неконстантных методов класса T имеет тип T *const, для
константных — имеет тип const T *const, для неустойчивых — volatile T
*const. Указатель this допускает разыменование (*this).
Применение this внутри методов допустимо, но чаще всего излишне.
Однако имеются ситуации, в которых явное использование this
необходимо. В частности:
• при сравнении адресов объектов, например:
if (this != someObj) /* … */
• в операторах return, например:
return *this;
Нестатические методы
класса (1 / 2)
За поведение (алгоритмическое обеспечение) реализованной в виде
класса абстракции предметной области отвечают функции-члены, или
методы, класса.
В отличие от атрибутов, методы класса существуют в единственном
экземпляре, причем даже тогда, когда ни один объект класса не
существует.
Подавляющее большинство методов класса оперирует нестатическими
атрибутами и в этом смысле может условно именоваться
нестатическими методами.
Для методов произвольного класса справедливо следующее:
• методы класса имеют доступ ко всем атрибутам класса;
• методы класса могут перегружать другие методы того же класса;
• нестатические методы класса получают в свое распоряжение
указатель this.
Нестатические методы
класса (2 / 2)
Например:
class Book
{ /* … */
Book(); // конструктор по умолчанию
// конструктор копирования
Book(const Book &aBook);
~Book(); // деструктор
/* … */
void printInfo();
string getISBN(char *format = NULL);
};
Встроенные методы
класса (1 / 2)
Функция-член, определенная внутри класса, по умолчанию является
встроенной, то есть подставляемой (на уровне машинного кода) в точку
своего вызова.
Чтобы интерпретироваться как встроенная, функция-член,
определенная вне класса, в теле класса должна явно
сопровождаться спецификатором inline.
Конструктор класса может быть объявлен как встроенный.
Деструктор класса также может быть встроенным.
Встроенные методы
класса (2 / 2)
Например:
class Account
{ /* … */
double getAmount() { return _amount; }
inline string getCurrCode()
{ return _currCode; }
inline string getAccInfo(char *format);
};
inline string
Account::getAccInfo(char *format)
{ /* … */ }
Константные методы
класса (1 / 2)
Методы класса могут модифицировать соответствующий объект (его
атрибуты), а могут не делать этого. «Безопасные» с точки зрения
работы с константными объектами методы могут помечаться
программистом как константные.
Константный метод не может модифицировать атрибуты класса (за
исключением изменчивых).
Применительно к константному объекту могут быть вызваны только
константные методы.
Константные методы могут перегружаться неконстантными методами с
идентичной сигнатурой и типом возвращаемого значения.
Применение константных методов с неконстантными объектами
обеспечивает дополнительный уровень безопасности кода при
разработке.
Константные методы
класса (2 / 2)
Например:
class Book
{ /* … */
void printInfo() const;
// перегруженные методы
string getChapTitle(int number);
string getChapTitle(int number) const;
};
Статические методы класса
Методы класса, обращающиеся только к статическим членам
данных, могут объявляться как статические.
Статическим методам класса не передается указатель this. Они не
могут быть константными или неустойчивыми.
Для вызова статического метода класса может использоваться
операция доступа с леводопустимым выражением или операция
разрешения области видимости с именем класса в качестве левого
операнда.
Например:
class BinaryTree
{ /* … */
public: static char *getFmt() { /* … */ }
private: static char *_format;
};
Неустойчивые методы класса
Методы класса могут объявляться как неустойчивые.
Неустойчивые методы класса являются единственной категорией
методов, которые (наряду с конструкторами и деструкторами) могут
вызываться применительно к неустойчивым объектам класса
(объектам, значение которых изменяется способом, не
обнаруживаемым компилятором).
Например:
class Timer
{
/* … */
void getCurTime() volatile;
/* … */
};
Указатели
на члены класса (1 / 3)
Наряду с «обычными» указателями на данные и глобальные функции
выделяют указатели на нестатические методы и атрибуты классов.
Примечание: Указатели на статические члены класса оформляются и
используются так же, как указатели на объекты, не являющиеся
членами класса.
Полный тип указателя на атрибут класса содержит имя класса и тип его
атрибута. Например:
class Screen {
public: short _height;
/* … */
};
short Screen::*psh = &Screen::_height;
Указатели
на члены класса (2 / 3)
Полный тип указателя на метод класса содержит имя класса, список
типов параметров (сигнатуру) метода и тип возвращаемого значения.
Например:
class Screen {
public:
int height() { return _height; }
int width() { return _width; }
/* … */
};
int (Screen::*pmeth1)() = NULL;
int (Screen::*pmeth2)() = &Screen::width;
// прочтите следующее определение
typedef Screen& (Screen::*Action)();
Указатели
на члены класса (3 / 3)
Адреса методов нельзя присваивать указателям на глобальные
функции, даже если их сигнатуры и типы возвращаемых значений
полностью совпадают:
• причина — методы класса находятся в области видимости класса-
владельца.
Адреса методов можно использовать для объявления формальных
параметров функций, типов возвращаемого значения и задания
значений параметров функций по умолчанию.
Для доступа к членам класса по указателям предназначены операции
.* и ->*. Например:
Screen *tmpScreen = new Screen();
short Screen::*psh = &Screen::_height;
tmpScreen->*psh = 80;
Дружественные классы и
функции
Реализованный в объектной модели C++ механизм дружественных
отношений позволяет классу разрешать доступ к своим неоткрытым
(закрытым и защищенным) членам.
Дружественные объекты не являются членами класса, поэтому на них
не распространяется действие спецификаторов доступа.
Отношения дружественности могут устанавливаться:
• между классом и функцией из пространства имен;
• между классом и методом другого класса;
• между двумя классами.
Проиллюстрируем синтаксис отношений дружественности на типовой
задаче перегрузки операций-функции >> и << для организации
потокового консольного и файлового ввода-вывода экземпляров
класса.
Потоковый ввод-вывод (1 / 2)
Консольный и файловый потоковый ввод-вывод экземпляра класса
организуется путем перегрузки операций-функций >> и <<, которая
производится следующим образом:
#include <iostream>
class Account
{
friend istream &
operator >>(istream &, Account &);
friend ostream &
operator <<(ostream &, Account &);
/* … */
};
Потоковый ввод-вывод (2 / 2)
Реализация каждого из дружественных методов тривиальна:
#include <iostream>
ostream &operator <<
(ostream &ostr, Account &acc)
{
ostr << "Name: " << acc._name << "; "
<< "Acc. No.: " << acc._number << "; "
/* << … */ << endl;
return ostr;
};
Для обеспечения файлового ввода-вывода используются потоки
классов ifstream (входной поток) и ofstream (выходной поток).
Дополнительная перегрузка операций >> и << не требуется.
Классы-объединения (1 / 2)
Объединение в C++ — специальная категория класса, в котором
члены данных физически располагаются, начиная с одного машинного
адреса.
Размер класса-объединения
определяется размерами его
атрибутов и равен
максимальному среди них.
В любой момент времени
значение может быть
присвоено только одному
атрибуту.
Классы-объединения (2 / 2)
Например:
union DataChunk
{
int intVal;
short shortVal;
char* ptrVal;
double dblVal;
};
DataChunk dc;
DataChunk *pdc = &dc;
dc.intVal = 0xFFAA;
pdc->shortVal = 077;
Безымянные объединения
За ненадобностью имя типа объединения может опускаться:
class IOPort
{ /* … */
union
{
int intVal;
short shortVal;
char* ptrVal;
double dblVal;
} _value;
} myPort;
myPort._value.intVal = 0xABCD;
Анонимные
объединения (1 / 2)
Объединение без имени, за которым не следует определение объекта,
называется анонимным. К его членам можно обращаться
непосредственно из той области видимости, в которой оно определено.
Анонимные объединения позволяют устранить один уровень доступа, у
них не может быть закрытых и защищенных членов, а также каких бы
то ни было методов.
Анонимные
объединения (2 / 2)
Например:
class IOPort
{
/* … */
union {
int intVal;
short shortVal;
char* ptrVal;
double dblVal;
};
} myPort;
myPort.ptrVal = NULL;
Битовые поля
в определении классов
Для хранения заданного числа двоичных разрядов может быть
определен член класса, называемый битовым полем. Его тип должен
быть знаковым или беззнаковым целым.
Определенные друг за другом битовые поля по возможности
«упаковываются» компилятором.
Например:
class IOPort
{
unsigned int _ioMode : 2;
unsigned int _enabled : 1;
/* … */
};
К битовому полю запрещено применять оператор взятия адреса.
Битовые поля не могут быть статическими членами класса.
Класс как область видимости
Класс — наряду с блоком, функцией и пространством имен —
является конструкцией C++, которая вводит в состав программы
одноименную область видимости. (Строго говоря, область видимости
в программу вводит определение класса, а именно его тело.)
Все члены класса видны в нем самом с момента своего объявления.
Порядок объявления членов класса важен: нельзя ссылаться на члены,
которые предстоит объявить позднее. Исключение составляет
разрешение имен в определения встроенных методов, а также имен
(статических членов), используемых как аргументы по умолчанию.
В области видимости класса находится не только его тело, но и
внешние определения его членов: методов и статических атрибутов.
Вложенные классы
Класс, объявленный внутри другого класса, называется вложенным (в
объемлющий класс). Определение вложенного класса может
находиться в любой секции объемлющего.
Имя вложенного класса известно в области видимости объемлющего
класса, но нигде более.
Объемлющий класс имеет право доступа только к открытым членам
вложенного, и обратно.
Как правило, вложенный класс объявляют закрытым в объемлющем, а
все члены вложенного класса объявляют открытыми.
Невстроенные методы вложенных классов определяются вне самого
внешнего из объемлющих классов.
Вложенный класс может быть объявлен в теле объемлющего, но не
определен в нем (принцип сокрытия реализации).
Конструкторы
и деструкторы (1 / 2)
Конструктор — метод класса, автоматически применяемый к каждому
экземпляру (объекту) класса перед первым использованием
(в случае динамического выделения памяти — после успешного
выполнения операции new).
Освобождение ресурсов, захваченных в конструкторе класса либо на
протяжении времени жизни соответствующего экземпляра,
осуществляет деструктор.
В связи с принятым по умолчанию почленным порядком инициализации
и копирования объектов класса в большинстве случаев возникает
необходимость в реализации, — наряду с конструктором по
умолчанию, — конструктора копирования и перегруженной
операции-функции присваивания operator=.
Конструкторы
и деструкторы (2 / 2)
Выполнение любого конструктора состоит из двух фаз:
• фаза явной (неявной) инициализации (обработка списка
инициализации);
• фаза вычислений (исполнение тела конструктора).
Конструктор не может определяться со спецификаторами const и
volatile. Константность и неустойчивость объекта устанавливается по
завершении работы конструктора и снимается перед вызовом
деструктора.
Инициализация
без конструктора (1 / 2)
Класс, все члены которого открыты, может задействовать механизм
явной позиционной инициализации, ассоциирующий значения в
списке инициализации с членами данных в соответствии с их порядком.
Например:
class TestCase
{
public:
int int_prm;
double dbl_prm;
string str_prm;
}; /* … */
TestCase tc1 = { 1, -3.14, "dictum factum"};
Инициализация
без конструктора (2 / 2)
Преимущества:
• скорость и эффективность;
• выполнение при запуске программы (для глобальных объектов).
Недостатки:
• пригодность только для классов, члены которых открыты;
• отсутствие поддержки инкапсуляции и абстрактных типов;
• требует предельной точности и аккуратности в применении.
Конструкторы
по умолчанию (1 / 2)
Конструктор по умолчанию не требует задания значений его
параметров, хотя таковые могут присутствовать в сигнатуре.
class TestCase
{
public:
TestCase(int ipr = 0, double dpr = 0.0);
/* … */
};
Наличие формальных параметров в конструкторе по умолчанию
позволяет сократить общее число конструкторов и объем исходного
кода.
Конструкторы
по умолчанию (2 / 2)
Если в классе определен хотя бы один конструктор с параметрами, то
при использовании класса со стандартными контейнерами и
динамическими массивами экземпляров конструктор по умолчанию
обязателен.
TestCase *ptcs = new TestCase[plan_size];
Если конструктор по умолчанию не определен, но существует хотя бы
один конструктор с параметрами, в определении объектов должны
присутствовать аргументы. Если ни одного конструктора не
определено, объект класса не инициализируется (память под
статическими объектами обнуляется).
Конструкторы с параметрами
Конструкторы с параметрами могут вызываться следующим образом:
class TestCase
{
public:
TestCase(int iprm) : int_prm (iprm) {}
private:
int int_prm;
};
TestCase tc1(10),
tc2 = TestCase(10),
tc3 = 10; // для одного аргумента
Массивы объектов
Массивы объектов класса определяются аналогично массивам
объектов базовых типов:
// для одного аргумента конструктора
TestCase testplan1[] = { 10, -5, 0, 127 };
// для нескольких аргументов конструктора
TestCase testplan2[5] = {
TestCase(10, 0.1),
TestCase(-5, -3.6),
TestCase(0, 0.0),
TestCase() // если есть констр. по умлч.
};
Закрытые и защищенные
конструкторы
Объявление конструктора класса защищенным или закрытым дает
возможность ограничить или полностью запретить отдельные способы
создания объектов класса.
В большинстве случаев закрытые и защищенные конструкторы
используются для:
• предотвращения копирования одного объекта в другой;
• указания на то, что конструктор должен вызываться только для
создания подобъектов базового класса в объекте производного
класса, а не создания объектов, доступных в коде программы
непосредственно.
Почленная инициализация
и присваивание (1 / 2)
Почленная инициализация по умолчанию — механизм
инициализации одного объекта класса другим объектом того же класса,
который активизируется независимо от наличия в определении класса
явного конструктора.
Почленная инициализация по умолчанию происходит в следующих
ситуациях:
• явная инициализация одного объекта другим;
• передача объекта класса в качестве аргумента функции;
• передача объекта класса в качестве возвращаемого функцией
значения;
• определение непустого стандартного последовательного
контейнера;
• вставка объекта класса в стандартный контейнер.
Почленная инициализация
и присваивание (2 / 2)
Почленная инициализация по умолчанию подавляется при наличии в
определении класса конструктора копирования.
Запрет почленной инициализации по умолчанию осуществляется
одним из следующих способов:
• объявление закрытого конструктора копирования (не действует для
методов класса и дружественных объектов);
• объявление конструктора копирования без его определения
(действует всюду).
Почленное присваивание по умолчанию — механизм присваивания
одному объекту класса значения другого объекта того же класса,
отличный от почленной инициализации по умолчанию использованием
копирующей операции-функции присваивания вместо конструктора
копирования.
Конструкторы копирования
Конструктор копирования принимает в качестве единственного
параметра константную ссылку на существующий объект класса.
В случае отсутствия явного конструктора копирования в определении
класса производится почленная инициализация объекта по умолчанию.
Например:
class TestCase
{
/* … */
TestCase(const TestCase &rtc);
/* … */
};
Конструкторы и операции
преобразования
Конструкторы преобразования служат для построения объектов
класса по одному или нескольким значениям иных типов.
Операции преобразования позволяют преобразовывать содержимое
объектов класса к требуемым типам данных.
Например:
class TestCase
{ // конструкторы преобразования
TestCase(const char *);
TestCase(const string &);
// операции преобразования
operator int () { return int_prm }
operator double () { return dbl_prm }
/* … */
};
Деструкторы. Виртуальные
деструкторы (1 / 2)
Деструктор — не принимающий параметров и не возвращающий
результат метод класса, автоматически вызываемый при выходе
объекта из области видимости и применении к указателю на объект
класса операции delete.
Например:
class TestCase
{
/* … */
virtual ~TestCase();
};
Примечание: деструктор не вызывается при выходе из области
видимости ссылки или указателя на объект.
Деструкторы. Виртуальные
деструкторы (2 / 2)
Типичные задачи деструктора:
• сброс содержимого программных буферов в долговременные
хранилища;
• освобождение (возврат) системных ресурсов, главным образом —
памяти;
• снятие блокировок, останов таймеров и т.д.
Для обеспечения корректного освобождения ресурсов объектами
производных классов деструкторы в иерархиях, как правило,
определяют как виртуальные.
Явный вызов деструкторов
Потребность в явном вызове деструктора обычно связана с
необходимостью уничтожить динамически размещенный объект без
освобождения памяти.
Например:
char *buf = new char[sizeof TestCase];
TestCase *ptc = new (buf) TestCase(100);
/* … */
ptc->~TestCase(); // вызов 1
TestCase *ptc = new (buf) TestCase(200);
/* … */
ptc->~TestCase(); // вызов 2
delete [] buf;
Список инициализации в
конструкторе (1 / 2)
Выполнение любого конструктора состоит из двух фаз:
• фаза явной (неявной) инициализации (обработка списка
инициализации);
• фаза вычислений (исполнение тела конструктора).
Обработка списка инициализации предполагает начальную
инициализацию членов данных, исполнение тела конструктора —
присваивание значений (в предварительно инициализированных
областях памяти).
Список инициализации в
конструкторе (2 / 2)
Присваивание значений членов данных, являющихся объектами
классов, в теле конструктора неэффективно ввиду ранее
произведенной инициализации по умолчанию. Присваивание значений
членов данных, представляющих базовые типы, по эффективности
равнозначно инициализации.
К началу выполнения тела конструктора инициализация всех
константных членов и членов-ссылок должна быть завершена.
Спасибо за внимание
Алексей Петров

Contenu connexe

Tendances

Lala qasanzade 9r2 c++
Lala qasanzade 9r2  c++Lala qasanzade 9r2  c++
Lala qasanzade 9r2 c++lala9r2
 
Lala qasanzade 9r2 c++
Lala qasanzade 9r2  c++Lala qasanzade 9r2  c++
Lala qasanzade 9r2 c++lala9r2
 
Лекция 1. Основы объектно-ориентированного программирования
Лекция 1. Основы объектно-ориентированного программированияЛекция 1. Основы объектно-ориентированного программирования
Лекция 1. Основы объектно-ориентированного программированияВиталий Емельянов
 
презентация конспекта лекций
презентация конспекта лекцийпрезентация конспекта лекций
презентация конспекта лекцийstudent_kai
 
20120309 formal semantics shilov_lecture05
20120309 formal semantics shilov_lecture0520120309 formal semantics shilov_lecture05
20120309 formal semantics shilov_lecture05Computer Science Club
 
20120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture0420120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture04Computer Science Club
 
Orxan9r2 c++
Orxan9r2 c++Orxan9r2 c++
Orxan9r2 c++orxan9r2
 
C++ осень 2012 лекция 7
C++ осень 2012 лекция 7C++ осень 2012 лекция 7
C++ осень 2012 лекция 7Technopark
 
C++ осень 2012 лекция 2
C++ осень 2012 лекция 2C++ осень 2012 лекция 2
C++ осень 2012 лекция 2Technopark
 
Borland C++ Builder освой самостоятельно
Borland C++ Builder освой самостоятельноBorland C++ Builder освой самостоятельно
Borland C++ Builder освой самостоятельноStAlKeRoV
 
Лекции и задания по рнр
Лекции и задания по рнрЛекции и задания по рнр
Лекции и задания по рнрRauan Ibraikhan
 

Tendances (15)

Lala qasanzade 9r2 c++
Lala qasanzade 9r2  c++Lala qasanzade 9r2  c++
Lala qasanzade 9r2 c++
 
ООП. Рекомендуемые информационные ресурсы
ООП. Рекомендуемые информационные ресурсыООП. Рекомендуемые информационные ресурсы
ООП. Рекомендуемые информационные ресурсы
 
Lala qasanzade 9r2 c++
Lala qasanzade 9r2  c++Lala qasanzade 9r2  c++
Lala qasanzade 9r2 c++
 
Лекция 1. Основы объектно-ориентированного программирования
Лекция 1. Основы объектно-ориентированного программированияЛекция 1. Основы объектно-ориентированного программирования
Лекция 1. Основы объектно-ориентированного программирования
 
презентация конспекта лекций
презентация конспекта лекцийпрезентация конспекта лекций
презентация конспекта лекций
 
20120309 formal semantics shilov_lecture05
20120309 formal semantics shilov_lecture0520120309 formal semantics shilov_lecture05
20120309 formal semantics shilov_lecture05
 
Методоллогии Agile
Методоллогии AgileМетодоллогии Agile
Методоллогии Agile
 
МиСПИСиТ (литература по курсу)
МиСПИСиТ (литература по курсу)МиСПИСиТ (литература по курсу)
МиСПИСиТ (литература по курсу)
 
20120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture0420120309 formal semantics shilov_lecture04
20120309 formal semantics shilov_lecture04
 
Orxan9r2 c++
Orxan9r2 c++Orxan9r2 c++
Orxan9r2 c++
 
МиСПИСиТ (разработка программного модуля)
МиСПИСиТ (разработка программного модуля)МиСПИСиТ (разработка программного модуля)
МиСПИСиТ (разработка программного модуля)
 
C++ осень 2012 лекция 7
C++ осень 2012 лекция 7C++ осень 2012 лекция 7
C++ осень 2012 лекция 7
 
C++ осень 2012 лекция 2
C++ осень 2012 лекция 2C++ осень 2012 лекция 2
C++ осень 2012 лекция 2
 
Borland C++ Builder освой самостоятельно
Borland C++ Builder освой самостоятельноBorland C++ Builder освой самостоятельно
Borland C++ Builder освой самостоятельно
 
Лекции и задания по рнр
Лекции и задания по рнрЛекции и задания по рнр
Лекции и задания по рнр
 

En vedette

Android осень 2013 лекция 1
Android осень 2013 лекция 1Android осень 2013 лекция 1
Android осень 2013 лекция 1Technopark
 
HighLoad весна 2014 лекция 6
HighLoad весна 2014 лекция 6HighLoad весна 2014 лекция 6
HighLoad весна 2014 лекция 6Technopark
 
АиСД осень 2012 лекция 1
АиСД осень 2012 лекция 1АиСД осень 2012 лекция 1
АиСД осень 2012 лекция 1Technopark
 
Тестирование весна 2014 смешанное занятие 3
Тестирование весна 2014 смешанное занятие 3Тестирование весна 2014 смешанное занятие 3
Тестирование весна 2014 смешанное занятие 3Technopark
 
HighLoad весна 2014 лекция 7
HighLoad весна 2014 лекция 7HighLoad весна 2014 лекция 7
HighLoad весна 2014 лекция 7Technopark
 
Безопасность весна 2014 лекция 7
Безопасность весна 2014 лекция 7Безопасность весна 2014 лекция 7
Безопасность весна 2014 лекция 7Technopark
 
СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"
СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"
СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"Technopark
 
Алгоритмы и структуры данных весна 2014 лекция 3
Алгоритмы и структуры данных весна 2014 лекция 3Алгоритмы и структуры данных весна 2014 лекция 3
Алгоритмы и структуры данных весна 2014 лекция 3Technopark
 
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...Technopark
 

En vedette (9)

Android осень 2013 лекция 1
Android осень 2013 лекция 1Android осень 2013 лекция 1
Android осень 2013 лекция 1
 
HighLoad весна 2014 лекция 6
HighLoad весна 2014 лекция 6HighLoad весна 2014 лекция 6
HighLoad весна 2014 лекция 6
 
АиСД осень 2012 лекция 1
АиСД осень 2012 лекция 1АиСД осень 2012 лекция 1
АиСД осень 2012 лекция 1
 
Тестирование весна 2014 смешанное занятие 3
Тестирование весна 2014 смешанное занятие 3Тестирование весна 2014 смешанное занятие 3
Тестирование весна 2014 смешанное занятие 3
 
HighLoad весна 2014 лекция 7
HighLoad весна 2014 лекция 7HighLoad весна 2014 лекция 7
HighLoad весна 2014 лекция 7
 
Безопасность весна 2014 лекция 7
Безопасность весна 2014 лекция 7Безопасность весна 2014 лекция 7
Безопасность весна 2014 лекция 7
 
СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"
СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"
СУБД 2013 Лекция №3 "Выборка данных (продолжение). Транзакции"
 
Алгоритмы и структуры данных весна 2014 лекция 3
Алгоритмы и структуры данных весна 2014 лекция 3Алгоритмы и структуры данных весна 2014 лекция 3
Алгоритмы и структуры данных весна 2014 лекция 3
 
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...
 

Similaire à C++ осень 2012 лекция 1

C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.Igor Shkulipa
 
C++ весна 2014 лекция 5
C++ весна 2014 лекция 5C++ весна 2014 лекция 5
C++ весна 2014 лекция 5Technopark
 
C++ Базовый. Занятие 01.
C++ Базовый. Занятие 01.C++ Базовый. Занятие 01.
C++ Базовый. Занятие 01.Igor Shkulipa
 
DBD lection 1. Intro in Database Design. In Russian.
DBD lection 1. Intro in Database Design. In Russian.DBD lection 1. Intro in Database Design. In Russian.
DBD lection 1. Intro in Database Design. In Russian.mikhaelsmirnov
 
рп по у пп практике в
рп по у пп практике врп по у пп практике в
рп по у пп практике вAnastasia Snegina
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.Igor Shkulipa
 
прикл.прогр птп 13 14
прикл.прогр птп 13 14прикл.прогр птп 13 14
прикл.прогр птп 13 14Anastasia Snegina
 
Шаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеШаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеSergey Nemchinsky
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6Technopark
 
Дополнительная общеразвивающая программа «Основы программирования В C/C++»
Дополнительная общеразвивающая программа «Основы программирования В C/C++»Дополнительная общеразвивающая программа «Основы программирования В C/C++»
Дополнительная общеразвивающая программа «Основы программирования В C/C++»rnmc7
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике втAnastasia Snegina
 
C++ осень 2013 лекция 8
C++ осень 2013 лекция 8C++ осень 2013 лекция 8
C++ осень 2013 лекция 8Technopark
 
Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"Sergey Nemchinsky
 

Similaire à C++ осень 2012 лекция 1 (20)

C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.
 
C++ весна 2014 лекция 5
C++ весна 2014 лекция 5C++ весна 2014 лекция 5
C++ весна 2014 лекция 5
 
C++ Базовый. Занятие 01.
C++ Базовый. Занятие 01.C++ Базовый. Занятие 01.
C++ Базовый. Занятие 01.
 
DBD lection 1. Intro in Database Design. In Russian.
DBD lection 1. Intro in Database Design. In Russian.DBD lection 1. Intro in Database Design. In Russian.
DBD lection 1. Intro in Database Design. In Russian.
 
Kursus esitlus
Kursus esitlusKursus esitlus
Kursus esitlus
 
Tdd php
Tdd phpTdd php
Tdd php
 
рп по у пп практике в
рп по у пп практике врп по у пп практике в
рп по у пп практике в
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.
 
прикл.прогр птп 13 14
прикл.прогр птп 13 14прикл.прогр птп 13 14
прикл.прогр птп 13 14
 
OO Design with C++: 0. Intro
OO Design with C++: 0. IntroOO Design with C++: 0. Intro
OO Design with C++: 0. Intro
 
Шаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеШаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. Введние
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6
 
Дополнительная общеразвивающая программа «Основы программирования В C/C++»
Дополнительная общеразвивающая программа «Основы программирования В C/C++»Дополнительная общеразвивающая программа «Основы программирования В C/C++»
Дополнительная общеразвивающая программа «Основы программирования В C/C++»
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике вт
 
Классы и объекты С#
Классы и объекты С#Классы и объекты С#
Классы и объекты С#
 
C++ осень 2013 лекция 8
C++ осень 2013 лекция 8C++ осень 2013 лекция 8
C++ осень 2013 лекция 8
 
SECR
SECRSECR
SECR
 
я.прогр птп
я.прогр птпя.прогр птп
я.прогр птп
 
A2
A2A2
A2
 
Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"Конспект лекций по курсу "Шаблоны разработки ПО"
Конспект лекций по курсу "Шаблоны разработки ПО"
 

Plus de Technopark

Лекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель PregelЛекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель PregelTechnopark
 
Лекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.RuЛекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.RuTechnopark
 
Лекция 13. YARN
Лекция 13. YARNЛекция 13. YARN
Лекция 13. YARNTechnopark
 
Лекция 12. Spark
Лекция 12. SparkЛекция 12. Spark
Лекция 12. SparkTechnopark
 
Лекция 10. Apache Mahout
Лекция 10. Apache MahoutЛекция 10. Apache Mahout
Лекция 10. Apache MahoutTechnopark
 
Лекция 9. ZooKeeper
Лекция 9. ZooKeeperЛекция 9. ZooKeeper
Лекция 9. ZooKeeperTechnopark
 
Лекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и HiveЛекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и HiveTechnopark
 
Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)Technopark
 
Лекция 5. MapReduce в Hadoop (алгоритмы)
Лекция 5. MapReduce в Hadoop (алгоритмы)Лекция 5. MapReduce в Hadoop (алгоритмы)
Лекция 5. MapReduce в Hadoop (алгоритмы)Technopark
 
Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)Technopark
 
Лекция 3. Распределённая файловая система HDFS
Лекция 3. Распределённая файловая система HDFSЛекция 3. Распределённая файловая система HDFS
Лекция 3. Распределённая файловая система HDFSTechnopark
 
Лекция 2. Основы Hadoop
Лекция 2. Основы HadoopЛекция 2. Основы Hadoop
Лекция 2. Основы HadoopTechnopark
 
Лекция 1. Введение в Big Data и MapReduce
Лекция 1. Введение в Big Data и MapReduceЛекция 1. Введение в Big Data и MapReduce
Лекция 1. Введение в Big Data и MapReduceTechnopark
 
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"Technopark
 
СУБД 2013 Лекция №9 "Безопасность баз данных"
СУБД 2013 Лекция №9 "Безопасность баз данных"СУБД 2013 Лекция №9 "Безопасность баз данных"
СУБД 2013 Лекция №9 "Безопасность баз данных"Technopark
 
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
СУБД 2013 Лекция №8 "Конфигурирование базы данных"СУБД 2013 Лекция №8 "Конфигурирование базы данных"
СУБД 2013 Лекция №8 "Конфигурирование базы данных"Technopark
 
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"Technopark
 
СУБД 2013 Лекция №5 "Определение узких мест"
СУБД 2013 Лекция №5 "Определение узких мест"СУБД 2013 Лекция №5 "Определение узких мест"
СУБД 2013 Лекция №5 "Определение узких мест"Technopark
 
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...Technopark
 
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...Technopark
 

Plus de Technopark (20)

Лекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель PregelЛекция 11. Вычислительная модель Pregel
Лекция 11. Вычислительная модель Pregel
 
Лекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.RuЛекция 14. Hadoop в Поиске Mail.Ru
Лекция 14. Hadoop в Поиске Mail.Ru
 
Лекция 13. YARN
Лекция 13. YARNЛекция 13. YARN
Лекция 13. YARN
 
Лекция 12. Spark
Лекция 12. SparkЛекция 12. Spark
Лекция 12. Spark
 
Лекция 10. Apache Mahout
Лекция 10. Apache MahoutЛекция 10. Apache Mahout
Лекция 10. Apache Mahout
 
Лекция 9. ZooKeeper
Лекция 9. ZooKeeperЛекция 9. ZooKeeper
Лекция 9. ZooKeeper
 
Лекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и HiveЛекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и Hive
 
Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)
 
Лекция 5. MapReduce в Hadoop (алгоритмы)
Лекция 5. MapReduce в Hadoop (алгоритмы)Лекция 5. MapReduce в Hadoop (алгоритмы)
Лекция 5. MapReduce в Hadoop (алгоритмы)
 
Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)
 
Лекция 3. Распределённая файловая система HDFS
Лекция 3. Распределённая файловая система HDFSЛекция 3. Распределённая файловая система HDFS
Лекция 3. Распределённая файловая система HDFS
 
Лекция 2. Основы Hadoop
Лекция 2. Основы HadoopЛекция 2. Основы Hadoop
Лекция 2. Основы Hadoop
 
Лекция 1. Введение в Big Data и MapReduce
Лекция 1. Введение в Big Data и MapReduceЛекция 1. Введение в Big Data и MapReduce
Лекция 1. Введение в Big Data и MapReduce
 
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"
 
СУБД 2013 Лекция №9 "Безопасность баз данных"
СУБД 2013 Лекция №9 "Безопасность баз данных"СУБД 2013 Лекция №9 "Безопасность баз данных"
СУБД 2013 Лекция №9 "Безопасность баз данных"
 
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
СУБД 2013 Лекция №8 "Конфигурирование базы данных"СУБД 2013 Лекция №8 "Конфигурирование базы данных"
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
 
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"
 
СУБД 2013 Лекция №5 "Определение узких мест"
СУБД 2013 Лекция №5 "Определение узких мест"СУБД 2013 Лекция №5 "Определение узких мест"
СУБД 2013 Лекция №5 "Определение узких мест"
 
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
 
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...
 

C++ осень 2012 лекция 1

  • 2. Обзор курса (1 / 3) Модуль №1. Объектная модель языка С++. Безопасное программирование • Лекция №1. Цели и задачи курса. Специальные вопросы инкапсуляции • Лекция №2. Специальные вопросы наследования и полиморфизма. Множественное и виртуальное наследование. Динамическая идентификация типов (RTTI) • Лекция №3. Шаблоны классов и методов. Обработка исключительных ситуаций. Обобщенное и безопасное программирование • Практикум №1 / 2. Проектирование / разработка полиморфной иерархии классов повышенного уровня сложности
  • 3. Обзор курса (2 / 3) Модуль №2. Библиотеки для промышленной разработки ПО: STL, Boost • Лекция №4. Введение в STL • Лекция №5. Реализация STL. Элементы функционального программирования • Лекция №6. Практическое введение в Boost • Практикум №3. Разработка и обеспечение безопасности полиморфной иерархии с шаблонами классов • Практикум №4. Оптимизация полиморфной иерархии классов с использованием элементов библиотек STL и Boost
  • 4. Обзор курса (3 / 3) Модуль №3. Шаблоны объектно-ориентированного проектирования. Основы промышленной разработки ПО • Лекция №7. Принципы и шаблоны объектно-ориентированного проектирования. Базовые и порождающие шаблоны • Лекция №8. Основные шаблоны проектирования однопоточных приложений. Структурные и поведенческие шаблоны • Лекция №9. Идиоматика C++. Основы рефакторинга и оптимизации исходного кода • Лекция №10. Качество исходного кода. Стандарты кодирования и основы командной разработки ПО • Практикум №5. Оптимизация полиморфной иерархии классов с использованием шаблонов объектно-ориентированного проектирования однопоточных приложений • Практикум №6. Рефакторинг и документирование объектно- ориентированного исходного кода
  • 5. Лекция №1. Цели и задачи курса. Специальные вопросы инкапсуляции • Цели, задачи, структура курса. • Определение и состав класса. • Работа с членами класса и указателями на них. • Дружественные классы и функции. • Вложенные типы. • Инициализация, копирование, преобразование и уничтожение объектов. • Инкапсуляция и вопросы производительности. • Постановка задач к практикуму №1.
  • 6. Цель и структура курса Цель курса — сформировать практические навыки и умения, необходимые специалистам по разработке программного обеспечения (ПО) для участия в проектах промышленной разработки среднего уровня сложности. Состав курса — 10 лекций, 6 практикумов: • осень 2012 (для сравнения) — 12 лекций, 4 практикума. Общая аудиторная нагрузка — 64 акад. часа: • лекционные занятия — 40 акад. часов; • практические работы — 24 акад. часа.
  • 7. Чему научимся? Практический результат (1 / 2) Обязательно: • моделировать систему при помощи UML-диаграмм классов; • разрабатывать код на языке C++; • использовать приемы обобщенного и безопасного программирования; • применять промышленные библиотеки STL, Boost; • внедрять в продукт классические архитектурные шаблоны GoF; • оценивать качество и выполнять рефакторинг исходного программного кода; • презентовать и защищать свои разработки перед аудиторией.
  • 8. Чему научимся? Практический результат (2 / 2) По желанию: • моделировать варианты использования продукта; • выполнять кодогенерацию по UML-моделям; • использовать новые возможности языка C++11; • писать многопоточные приложения; • реализовывать графический интерфейс пользователя в Qt.
  • 9. Организационные положения Расписание занятий: • постановка задач к практикумам — на лекциях №№1, 2, 3, 5, 7 и 9 (работа выполняется в командах!). Регламент занятия: • продолжительность — 4 акад. часа с 1 или 2 перерывами общей продолжительностью до 10 минут; • вопросы — общезначимые: в любое время (во время пауз или по поднятию руки!), индивидуальные: в перерыве или после занятия; • ведение видеосъемки (задавайте вопросы по существу и разборчиво!). Знакомство с аудиторией: • известные языки программирования (C, C++, Java); • опыт разработки, известные среды и технологии.
  • 10. Рекомендуемая литература (1 / 3) • Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. Приемы объектно- ориентированного проектирования. Паттерны проектирования. — Питер, 2007. — 366 с. • Кериевски Дж. Рефакторинг с использованием шаблонов. — Вильямс, 2006. — 400 с. • Липпман С., Лажойе Ж. Язык программирования C++. Вводный курс. — Невский Диалект, ДМК Пресс. — 1104 с. • Липпман С., Лажойе Ж., Му Б. Язык программирования C++. Вводный курс. —Вильямс, 2007. — 4-е изд. — 896 с. • Лишнер Р. STL. Карманный справочник. — Питер, 2005. — 188 с. • Макконнелл С. Совершенный код. Мастер-класс. — Русская редакция, 2012. — 896 с.
  • 11. Рекомендуемая литература (2 / 3) • Мюссер Д., Дердж Ж., Сейни А. C++ и STL. Справочное руководство. — Вильямс, 2010. — 432 с. • Саттер Г. Новые сложные задачи на C++. — Вильямс, 2005. — 272 с. • Саттер Г. Решение сложных задач на C++. — Вильямс, 2008. — 400 с. • Саттер Г., Александреску А. Стандарты программирования на C++. — Вильямс, 2008. — 224 с. • Седжвик Р. Алгоритмы на C++. — Вильямс, 2011. — 1056 с. • Страуструп Б. Программирование. Принципы и практика использования C++. — Вильямс, 2011. — 1248 с. • Страуструп Б. Язык программирования C++. — Бином, 2011. — 1136 с.
  • 12. Рекомендуемая литература (3 / 3) • Фаулер М. Рефакторинг. Улучшение существующего кода. — Символ-Плюс, 2008. — 432 с. • Шилдт Г. Полный справочник по C++. — Вильямс, 2007. — 800 с. • Demming, R., Duffy, D.J. Introduction to the Boost C++ Libraries; Volume I – Foundations (Datasim Education BV, 2010). • Demming, R., Duffy, D.J. Introduction to the Boost C++ Libraries; Volume II – Advanced Libraries (Datasim Education BV, 2012). • Musser, D.R., Saini, A. STL Tutorial and Reference Guide: C++ Programming with the Standard Template Library (Addison-Wesley, 1995). • Schäling, B. The Boost C++ Libraries. URL: http://en.highscore.de/cpp/boost/. • Standard Template Library Programmer’s Guide. URL: http://www.sgi.com/tech/stl/
  • 13. Web-ресурсы • Официальный Web-сайт проекта Boost: http://www.boost.org/. • Официальный Web-сайт проекта Eclipse: http://www.eclipse.org/. • Справка по языкам C / C++: http://ru.cppreference.com/w/, http://en.cppreference.com/w/.
  • 15. Инкапсуляция — базовый принцип ООП Инкапсуляция, или сокрытие реализации, является фундаментом объектного подхода к разработке ПО. Следуя данному подходу, программист рассматривает задачу в терминах предметной области, а создаваемый им продукт видит как совокупность абстрактных сущностей — классов (в свою очередь формально являющихся пользовательскими типами). Инкапсуляция предотвращает прямой доступ к внутреннему представлению класса из других классов и функций программы. Без нее теряют смысл остальные основополагающие принципы объектно-ориентированного программирования (ООП): наследование и полиморфизм. Сущность инкапсуляции можно отразить формулой: Открытый интерфейс + скрытая реализация
  • 16. Класс: в узком или широком смысле? Принцип инкапсуляции распространяется не только на классы (class), но и на структуры (struct), а также объединения (union). Это связано с расширительным толкованием понятия «класс» в стандарте языка C++. Понятие «класс» в языке C++ может трактоваться в узком или широком смысле. Класс в узком смысле — одноименный составной пользовательский тип данных, являющийся контейнером для данных и алгоритмов их обработки. Вводится в текст программы определением типа со спецификатором class. Класс в широком смысле — любой составной пользовательский тип данных, агрегирующий данные и алгоритмы их обработки. Вводится в текст программы определением типа с одним из спецификаторов struct, union или class.
  • 17. Определение класса (1 / 2) Простейшее определение класса в языке C++ имеет вид: // заголовок класса <спецификатор класса> <имя класса> { // тело класса [<члены класса>] }; где <спецификатор класса> — ключевое слово class, union или struct, <имя класса> — правильный идентификатор, а <члены класса> определены в соответствии с требуемым уровнем доступа (открытые, закрытые, защищенные). Каждое определение класса вводит новый тип данных. Тело класса определяет полный перечень его членов, который не может быть расширен после закрытия тела.
  • 18. Определение класса (2 / 2) Например: // пустой класс class Document { }; // непустой класс class Book { public: Book(); private: string _author, _title; };
  • 19. Объявление класса (1 / 2) Объявление класса вида <спецификатор класса> <имя класса>; вводит в программу имя класса и указывает его природу, не определяя состав атрибутов, методов и иных составных частей класса. В случае если класс объявлен, но не определен, допускается: • определять ссылки и указатели на объект класса; • определять член другого класса как ссылку или указатель на данный класс. В случае если класс объявлен, но не определен, запрещается: • определять объект класса; • определять член другого класса как принадлежащий данному классу; • разыменовывать указатели на объект класса; • использовать ссылки и указатели для доступа к членам класса.
  • 20. Объявление класса (2 / 2) Например: // объявление класса class Account; // можно // определения объектов class Account acc; // нельзя Account *pAcc = NULL; // можно void foo(const Account *pA); // ???
  • 21. Объект класса (1 / 2) Выделение памяти под объект класса происходит при определении такого объекта, ссылки на объект или указателя на него. Объект класса имеет размер, достаточный для размещения в нем всех (нестатических) атрибутов, собственную копию каждого из которых имеет каждый индивидуальный объект. Объект класса характеризуется областью видимости и обладает временем жизни. Объекты одного класса могут присваиваться друг другу. В отсутствие в определении класса специального метода (конструктора копирования) копирование объектов эквивалентно побайтовому копированию каждого атрибута. Будучи параметром или возвращаемым значением функции, объект класса передается по значению.
  • 22. Объект класса (2 / 2) Например: // определение класса class Account { /* … */ }; class Deposit { /* … */ } deposit; // определения объектов: правильно class Account acc; Account *pAcc = new Account(100); Account &rAcc = acc; // определения объектов: ??? class Account *&prAcc = pAcc; Account &rAcc2 = &acc;
  • 23. Константный объект класса (1 / 2) Объект класса (как и объект базового типа) может быть объявлен константным. Константный объект не допускает изменения значения его атрибутов на протяжении всего времени жизни объекта, за исключением • времени работы конструктора (объект создается); • времени работы деструктора (объект уничтожается).
  • 24. Константный объект класса (2 / 2) Неизменность членов-данных, являющихся указателями, распространяется только на их значение (адрес) и не распространяется на содержимое областей памяти, которые они адресуют. Примечание: Модификация адресуемых таким образом областей памяти демонстрирует «плохой стиль» программирования. Например: const Document myDocument;
  • 25. Состав класса (1 / 2) В состав класса на языке C++ могут входить следующие элементы (начало): • атрибуты (данные-члены — содержательная сторона класса): • статические (со спецификатором static), в том числе константные (со спецификатором const); • неустойчивые (со спецификатором volatile); • изменчивые (со спецификатором mutable); • прочие (без формальных спецификаторов); • методы (функции-члены — алгоритмическая сторона класса), в том числе специальные (конструкторы, деструкторы): • встроенные (со спецификатором inline); • константные (со спецификатором const); • статические (со спецификатором static); • неустойчивые (со спецификатором volatile); • прочие (без формальных спецификаторов);
  • 26. Состав класса (2 / 2) В состав класса на языке C++ могут входить следующие элементы (окончание): • описания дружественных объектов: • прототипы дружественных функций; • описания дружественных классов; • определения типов; • битовые поля; • вложенные классы.
  • 27. Нестатические члены данных (1 / 2) За содержательную сторону реализованной в виде класса абстракции предметной области отвечают данные-члены, или атрибуты, класса. Чаще всего каждый экземпляр (объект) класса имеет собственный набор атрибутов. Назовем такие атрибуты класса нестатическими. Нестатические члены данных сопоставляются с конкретным экземпляром класса и тиражируются. Время жизни такого члена данных равно времени жизни объекта. Нестатические члены данных нельзя инициализировать в теле класса. Для обращения к нестатическим членам данных служат операции доступа (. или ->), левым операндом которых выступает леводопустимое выражение: идентификатор объекта, ссылка или указатель на объект (допустимый вариант — this, см. далее).
  • 28. Нестатические члены данных (2 / 2) Например: class Book { /* … */ int _pages; string _title; vector<string> _chapTitles; /* … */ } book; Book *pBook = &book; /* … */ book._pages = 100; // pBook->_pages = 100; (*pBook)._pages = 100;
  • 29. Статические члены данных (1 / 3) Статический член данных класса — это глобальный объект, совместно используемый всеми объектами своего класса. Статические объекты не тиражируются и существуют даже при отсутствии экземпляров, поскольку связаны не с переменной (объектом), а типом (классом). Преимущества статических членов данных перед глобальными объектами состоят в том, что: • статические члены находятся в области видимости класса, а не в глобальном пространстве имен; • на статические члены распространяется действие спецификаторов доступа.
  • 30. Статические члены данных (2 / 3) В общем случае статический член инициализируется вне определения класса. Определение статического члена данных в программе может быть лишь одно. Примечание: В качестве исключения константный статический член целого типа может быть проинициализирован константой внутри тела класса. В этом случае он трактуется как константное выражение (именованная константа). Для обращения к статическому члену класса может использоваться операция доступа с леводопустимым выражением или операция разрешения области видимости с именем класса в качестве левого операнда. Статический член данных может иметь тот же тип класса, членом которого он является, а также быть аргументом по умолчанию для метода класса.
  • 31. Статические члены данных (3 / 3) Например: class BinaryTree { /* … */ static char delimiter; static const short base = 10; static const char *_format; }; char BinaryTree::delimiter = ','; const char *BinaryTree::_format = "(%d) %d,_"; BinaryTree tree; /* … */ tree.delimiter = ' '; BinaryTree::delimiter = ';';
  • 32. Неустойчивые объекты (1 / 2) Неустойчивые, или асинхронно изменяемые (volatile), объекты могут изменяться незаметно для компилятора. Пример: переменная, обновляемая значением системных часов или значением, полученным через системный порт. Целью определения объекта как неустойчивого является информирование компилятора о том, что тот не может определить, каким образом может изменяться значение данного объекта. Спецификатор volatile сообщает компилятору о том, что при работе с данным объектом не следует выполнять оптимизацию кода.
  • 33. Неустойчивые объекты (2 / 2) Допустимы неустойчивые объекты скалярных и составных типов, указатели на неустойчивые объекты, неустойчивые массивы: • в неустойчивом массиве неустойчивым считается каждый элемент; • в неустойчивом экземпляре (объекте) класса неустойчивым считается каждый член данных. Объекты классов неустойчивы целиком. Например: // неустойчивый скаляр volatile unsigned long timer; // неустойчивый массив volatile short ports[size]; // указатель на неустойчивый объект класса volatile Timer *tmr; Для преобразования неустойчивого типа в устойчивый используется const_cast.
  • 34. Изменчивые члены данных Атрибуты класса, допускающие модификацию при любом использовании объекта, должны определяться как изменчивые. Изменчивые атрибуты не являются константными, даже будучи членами константного объекта, что позволяет модифицировать их значения, в том числе константными методами. Например: class Book { /* … */ mutable int _currentPage; /* … */ void locate(const int &value) const { /* … */_currentPage = value; /* … */ } };
  • 35. Указатель this Указатель this — неявно определяемый константный указатель на объект класса, через который происходит вызов соответствующего нестатического метода. Для неконстантных методов класса T имеет тип T *const, для константных — имеет тип const T *const, для неустойчивых — volatile T *const. Указатель this допускает разыменование (*this). Применение this внутри методов допустимо, но чаще всего излишне. Однако имеются ситуации, в которых явное использование this необходимо. В частности: • при сравнении адресов объектов, например: if (this != someObj) /* … */ • в операторах return, например: return *this;
  • 36. Нестатические методы класса (1 / 2) За поведение (алгоритмическое обеспечение) реализованной в виде класса абстракции предметной области отвечают функции-члены, или методы, класса. В отличие от атрибутов, методы класса существуют в единственном экземпляре, причем даже тогда, когда ни один объект класса не существует. Подавляющее большинство методов класса оперирует нестатическими атрибутами и в этом смысле может условно именоваться нестатическими методами. Для методов произвольного класса справедливо следующее: • методы класса имеют доступ ко всем атрибутам класса; • методы класса могут перегружать другие методы того же класса; • нестатические методы класса получают в свое распоряжение указатель this.
  • 37. Нестатические методы класса (2 / 2) Например: class Book { /* … */ Book(); // конструктор по умолчанию // конструктор копирования Book(const Book &aBook); ~Book(); // деструктор /* … */ void printInfo(); string getISBN(char *format = NULL); };
  • 38. Встроенные методы класса (1 / 2) Функция-член, определенная внутри класса, по умолчанию является встроенной, то есть подставляемой (на уровне машинного кода) в точку своего вызова. Чтобы интерпретироваться как встроенная, функция-член, определенная вне класса, в теле класса должна явно сопровождаться спецификатором inline. Конструктор класса может быть объявлен как встроенный. Деструктор класса также может быть встроенным.
  • 39. Встроенные методы класса (2 / 2) Например: class Account { /* … */ double getAmount() { return _amount; } inline string getCurrCode() { return _currCode; } inline string getAccInfo(char *format); }; inline string Account::getAccInfo(char *format) { /* … */ }
  • 40. Константные методы класса (1 / 2) Методы класса могут модифицировать соответствующий объект (его атрибуты), а могут не делать этого. «Безопасные» с точки зрения работы с константными объектами методы могут помечаться программистом как константные. Константный метод не может модифицировать атрибуты класса (за исключением изменчивых). Применительно к константному объекту могут быть вызваны только константные методы. Константные методы могут перегружаться неконстантными методами с идентичной сигнатурой и типом возвращаемого значения. Применение константных методов с неконстантными объектами обеспечивает дополнительный уровень безопасности кода при разработке.
  • 41. Константные методы класса (2 / 2) Например: class Book { /* … */ void printInfo() const; // перегруженные методы string getChapTitle(int number); string getChapTitle(int number) const; };
  • 42. Статические методы класса Методы класса, обращающиеся только к статическим членам данных, могут объявляться как статические. Статическим методам класса не передается указатель this. Они не могут быть константными или неустойчивыми. Для вызова статического метода класса может использоваться операция доступа с леводопустимым выражением или операция разрешения области видимости с именем класса в качестве левого операнда. Например: class BinaryTree { /* … */ public: static char *getFmt() { /* … */ } private: static char *_format; };
  • 43. Неустойчивые методы класса Методы класса могут объявляться как неустойчивые. Неустойчивые методы класса являются единственной категорией методов, которые (наряду с конструкторами и деструкторами) могут вызываться применительно к неустойчивым объектам класса (объектам, значение которых изменяется способом, не обнаруживаемым компилятором). Например: class Timer { /* … */ void getCurTime() volatile; /* … */ };
  • 44. Указатели на члены класса (1 / 3) Наряду с «обычными» указателями на данные и глобальные функции выделяют указатели на нестатические методы и атрибуты классов. Примечание: Указатели на статические члены класса оформляются и используются так же, как указатели на объекты, не являющиеся членами класса. Полный тип указателя на атрибут класса содержит имя класса и тип его атрибута. Например: class Screen { public: short _height; /* … */ }; short Screen::*psh = &Screen::_height;
  • 45. Указатели на члены класса (2 / 3) Полный тип указателя на метод класса содержит имя класса, список типов параметров (сигнатуру) метода и тип возвращаемого значения. Например: class Screen { public: int height() { return _height; } int width() { return _width; } /* … */ }; int (Screen::*pmeth1)() = NULL; int (Screen::*pmeth2)() = &Screen::width; // прочтите следующее определение typedef Screen& (Screen::*Action)();
  • 46. Указатели на члены класса (3 / 3) Адреса методов нельзя присваивать указателям на глобальные функции, даже если их сигнатуры и типы возвращаемых значений полностью совпадают: • причина — методы класса находятся в области видимости класса- владельца. Адреса методов можно использовать для объявления формальных параметров функций, типов возвращаемого значения и задания значений параметров функций по умолчанию. Для доступа к членам класса по указателям предназначены операции .* и ->*. Например: Screen *tmpScreen = new Screen(); short Screen::*psh = &Screen::_height; tmpScreen->*psh = 80;
  • 47. Дружественные классы и функции Реализованный в объектной модели C++ механизм дружественных отношений позволяет классу разрешать доступ к своим неоткрытым (закрытым и защищенным) членам. Дружественные объекты не являются членами класса, поэтому на них не распространяется действие спецификаторов доступа. Отношения дружественности могут устанавливаться: • между классом и функцией из пространства имен; • между классом и методом другого класса; • между двумя классами. Проиллюстрируем синтаксис отношений дружественности на типовой задаче перегрузки операций-функции >> и << для организации потокового консольного и файлового ввода-вывода экземпляров класса.
  • 48. Потоковый ввод-вывод (1 / 2) Консольный и файловый потоковый ввод-вывод экземпляра класса организуется путем перегрузки операций-функций >> и <<, которая производится следующим образом: #include <iostream> class Account { friend istream & operator >>(istream &, Account &); friend ostream & operator <<(ostream &, Account &); /* … */ };
  • 49. Потоковый ввод-вывод (2 / 2) Реализация каждого из дружественных методов тривиальна: #include <iostream> ostream &operator << (ostream &ostr, Account &acc) { ostr << "Name: " << acc._name << "; " << "Acc. No.: " << acc._number << "; " /* << … */ << endl; return ostr; }; Для обеспечения файлового ввода-вывода используются потоки классов ifstream (входной поток) и ofstream (выходной поток). Дополнительная перегрузка операций >> и << не требуется.
  • 50. Классы-объединения (1 / 2) Объединение в C++ — специальная категория класса, в котором члены данных физически располагаются, начиная с одного машинного адреса. Размер класса-объединения определяется размерами его атрибутов и равен максимальному среди них. В любой момент времени значение может быть присвоено только одному атрибуту.
  • 51. Классы-объединения (2 / 2) Например: union DataChunk { int intVal; short shortVal; char* ptrVal; double dblVal; }; DataChunk dc; DataChunk *pdc = &dc; dc.intVal = 0xFFAA; pdc->shortVal = 077;
  • 52. Безымянные объединения За ненадобностью имя типа объединения может опускаться: class IOPort { /* … */ union { int intVal; short shortVal; char* ptrVal; double dblVal; } _value; } myPort; myPort._value.intVal = 0xABCD;
  • 53. Анонимные объединения (1 / 2) Объединение без имени, за которым не следует определение объекта, называется анонимным. К его членам можно обращаться непосредственно из той области видимости, в которой оно определено. Анонимные объединения позволяют устранить один уровень доступа, у них не может быть закрытых и защищенных членов, а также каких бы то ни было методов.
  • 54. Анонимные объединения (2 / 2) Например: class IOPort { /* … */ union { int intVal; short shortVal; char* ptrVal; double dblVal; }; } myPort; myPort.ptrVal = NULL;
  • 55. Битовые поля в определении классов Для хранения заданного числа двоичных разрядов может быть определен член класса, называемый битовым полем. Его тип должен быть знаковым или беззнаковым целым. Определенные друг за другом битовые поля по возможности «упаковываются» компилятором. Например: class IOPort { unsigned int _ioMode : 2; unsigned int _enabled : 1; /* … */ }; К битовому полю запрещено применять оператор взятия адреса. Битовые поля не могут быть статическими членами класса.
  • 56. Класс как область видимости Класс — наряду с блоком, функцией и пространством имен — является конструкцией C++, которая вводит в состав программы одноименную область видимости. (Строго говоря, область видимости в программу вводит определение класса, а именно его тело.) Все члены класса видны в нем самом с момента своего объявления. Порядок объявления членов класса важен: нельзя ссылаться на члены, которые предстоит объявить позднее. Исключение составляет разрешение имен в определения встроенных методов, а также имен (статических членов), используемых как аргументы по умолчанию. В области видимости класса находится не только его тело, но и внешние определения его членов: методов и статических атрибутов.
  • 57. Вложенные классы Класс, объявленный внутри другого класса, называется вложенным (в объемлющий класс). Определение вложенного класса может находиться в любой секции объемлющего. Имя вложенного класса известно в области видимости объемлющего класса, но нигде более. Объемлющий класс имеет право доступа только к открытым членам вложенного, и обратно. Как правило, вложенный класс объявляют закрытым в объемлющем, а все члены вложенного класса объявляют открытыми. Невстроенные методы вложенных классов определяются вне самого внешнего из объемлющих классов. Вложенный класс может быть объявлен в теле объемлющего, но не определен в нем (принцип сокрытия реализации).
  • 58. Конструкторы и деструкторы (1 / 2) Конструктор — метод класса, автоматически применяемый к каждому экземпляру (объекту) класса перед первым использованием (в случае динамического выделения памяти — после успешного выполнения операции new). Освобождение ресурсов, захваченных в конструкторе класса либо на протяжении времени жизни соответствующего экземпляра, осуществляет деструктор. В связи с принятым по умолчанию почленным порядком инициализации и копирования объектов класса в большинстве случаев возникает необходимость в реализации, — наряду с конструктором по умолчанию, — конструктора копирования и перегруженной операции-функции присваивания operator=.
  • 59. Конструкторы и деструкторы (2 / 2) Выполнение любого конструктора состоит из двух фаз: • фаза явной (неявной) инициализации (обработка списка инициализации); • фаза вычислений (исполнение тела конструктора). Конструктор не может определяться со спецификаторами const и volatile. Константность и неустойчивость объекта устанавливается по завершении работы конструктора и снимается перед вызовом деструктора.
  • 60. Инициализация без конструктора (1 / 2) Класс, все члены которого открыты, может задействовать механизм явной позиционной инициализации, ассоциирующий значения в списке инициализации с членами данных в соответствии с их порядком. Например: class TestCase { public: int int_prm; double dbl_prm; string str_prm; }; /* … */ TestCase tc1 = { 1, -3.14, "dictum factum"};
  • 61. Инициализация без конструктора (2 / 2) Преимущества: • скорость и эффективность; • выполнение при запуске программы (для глобальных объектов). Недостатки: • пригодность только для классов, члены которых открыты; • отсутствие поддержки инкапсуляции и абстрактных типов; • требует предельной точности и аккуратности в применении.
  • 62. Конструкторы по умолчанию (1 / 2) Конструктор по умолчанию не требует задания значений его параметров, хотя таковые могут присутствовать в сигнатуре. class TestCase { public: TestCase(int ipr = 0, double dpr = 0.0); /* … */ }; Наличие формальных параметров в конструкторе по умолчанию позволяет сократить общее число конструкторов и объем исходного кода.
  • 63. Конструкторы по умолчанию (2 / 2) Если в классе определен хотя бы один конструктор с параметрами, то при использовании класса со стандартными контейнерами и динамическими массивами экземпляров конструктор по умолчанию обязателен. TestCase *ptcs = new TestCase[plan_size]; Если конструктор по умолчанию не определен, но существует хотя бы один конструктор с параметрами, в определении объектов должны присутствовать аргументы. Если ни одного конструктора не определено, объект класса не инициализируется (память под статическими объектами обнуляется).
  • 64. Конструкторы с параметрами Конструкторы с параметрами могут вызываться следующим образом: class TestCase { public: TestCase(int iprm) : int_prm (iprm) {} private: int int_prm; }; TestCase tc1(10), tc2 = TestCase(10), tc3 = 10; // для одного аргумента
  • 65. Массивы объектов Массивы объектов класса определяются аналогично массивам объектов базовых типов: // для одного аргумента конструктора TestCase testplan1[] = { 10, -5, 0, 127 }; // для нескольких аргументов конструктора TestCase testplan2[5] = { TestCase(10, 0.1), TestCase(-5, -3.6), TestCase(0, 0.0), TestCase() // если есть констр. по умлч. };
  • 66. Закрытые и защищенные конструкторы Объявление конструктора класса защищенным или закрытым дает возможность ограничить или полностью запретить отдельные способы создания объектов класса. В большинстве случаев закрытые и защищенные конструкторы используются для: • предотвращения копирования одного объекта в другой; • указания на то, что конструктор должен вызываться только для создания подобъектов базового класса в объекте производного класса, а не создания объектов, доступных в коде программы непосредственно.
  • 67. Почленная инициализация и присваивание (1 / 2) Почленная инициализация по умолчанию — механизм инициализации одного объекта класса другим объектом того же класса, который активизируется независимо от наличия в определении класса явного конструктора. Почленная инициализация по умолчанию происходит в следующих ситуациях: • явная инициализация одного объекта другим; • передача объекта класса в качестве аргумента функции; • передача объекта класса в качестве возвращаемого функцией значения; • определение непустого стандартного последовательного контейнера; • вставка объекта класса в стандартный контейнер.
  • 68. Почленная инициализация и присваивание (2 / 2) Почленная инициализация по умолчанию подавляется при наличии в определении класса конструктора копирования. Запрет почленной инициализации по умолчанию осуществляется одним из следующих способов: • объявление закрытого конструктора копирования (не действует для методов класса и дружественных объектов); • объявление конструктора копирования без его определения (действует всюду). Почленное присваивание по умолчанию — механизм присваивания одному объекту класса значения другого объекта того же класса, отличный от почленной инициализации по умолчанию использованием копирующей операции-функции присваивания вместо конструктора копирования.
  • 69. Конструкторы копирования Конструктор копирования принимает в качестве единственного параметра константную ссылку на существующий объект класса. В случае отсутствия явного конструктора копирования в определении класса производится почленная инициализация объекта по умолчанию. Например: class TestCase { /* … */ TestCase(const TestCase &rtc); /* … */ };
  • 70. Конструкторы и операции преобразования Конструкторы преобразования служат для построения объектов класса по одному или нескольким значениям иных типов. Операции преобразования позволяют преобразовывать содержимое объектов класса к требуемым типам данных. Например: class TestCase { // конструкторы преобразования TestCase(const char *); TestCase(const string &); // операции преобразования operator int () { return int_prm } operator double () { return dbl_prm } /* … */ };
  • 71. Деструкторы. Виртуальные деструкторы (1 / 2) Деструктор — не принимающий параметров и не возвращающий результат метод класса, автоматически вызываемый при выходе объекта из области видимости и применении к указателю на объект класса операции delete. Например: class TestCase { /* … */ virtual ~TestCase(); }; Примечание: деструктор не вызывается при выходе из области видимости ссылки или указателя на объект.
  • 72. Деструкторы. Виртуальные деструкторы (2 / 2) Типичные задачи деструктора: • сброс содержимого программных буферов в долговременные хранилища; • освобождение (возврат) системных ресурсов, главным образом — памяти; • снятие блокировок, останов таймеров и т.д. Для обеспечения корректного освобождения ресурсов объектами производных классов деструкторы в иерархиях, как правило, определяют как виртуальные.
  • 73. Явный вызов деструкторов Потребность в явном вызове деструктора обычно связана с необходимостью уничтожить динамически размещенный объект без освобождения памяти. Например: char *buf = new char[sizeof TestCase]; TestCase *ptc = new (buf) TestCase(100); /* … */ ptc->~TestCase(); // вызов 1 TestCase *ptc = new (buf) TestCase(200); /* … */ ptc->~TestCase(); // вызов 2 delete [] buf;
  • 74. Список инициализации в конструкторе (1 / 2) Выполнение любого конструктора состоит из двух фаз: • фаза явной (неявной) инициализации (обработка списка инициализации); • фаза вычислений (исполнение тела конструктора). Обработка списка инициализации предполагает начальную инициализацию членов данных, исполнение тела конструктора — присваивание значений (в предварительно инициализированных областях памяти).
  • 75. Список инициализации в конструкторе (2 / 2) Присваивание значений членов данных, являющихся объектами классов, в теле конструктора неэффективно ввиду ранее произведенной инициализации по умолчанию. Присваивание значений членов данных, представляющих базовые типы, по эффективности равнозначно инициализации. К началу выполнения тела конструктора инициализация всех константных членов и членов-ссылок должна быть завершена.