Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Чтобы сделать друзей класса видимыми его пользователям, их обычно объявляют вне класса в том же заголовке, что и сам класс. Таким образом, в заголовке Sales_data
следует предоставить отдельные объявления (кроме объявлений дружественными в теле класса) для функций read()
, print()
и add()
.
Многие компиляторы не выполняют правило, согласно которому дружественные функции должны быть объявлены вне класса, прежде чем они будут применены.
Некоторые компиляторы позволяют вызвать дружественную функцию, когда для нее нет обычного объявления. Даже если ваш компилятор позволяет такие вызовы, имеет смысл предоставлять отдельные объявления для дружественных функций. Так не придется переделывать весь код, если вы перейдете на компилятор, который выполняет это правило.
Упражнение 7.20. Когда полезны дружественные отношения? Укажите преимущества и недостатки их использования.
Упражнение 7.21. Измените свой класс Sales_data
так, чтобы скрыть его реализацию. Написанные вами программы, которые использовали операции класса Sales_data
, должны продолжить работать. Перекомпилируйте эти программы с новым определением класса, чтобы проверить, остались ли они работоспособными.
Упражнение 7.22. Измените свой класс Person
так, чтобы скрыть его реализацию.
7.3. Дополнительные средства класса
Хотя класс Sales_data
довольно прост, он все же позволил исследовать немало средств поддержки классов. В этом разделе рассматриваются некоторые из дополнительных средств, связанных с классом, которые класс Sales_data
не будет использовать. К этим средствам относятся типы-члены (type member), внутриклассовые инициализаторы для типов-членов класса, изменяемые переменные-члены, встраиваемые функции-члены, функции-члены, возвращающие *this
, а также подробности определения и использования типов класса и дружественных классов.
7.3.1. Снова о членах класса
Для исследования некоторых из дополнительных средств определим пару взаимодействующих классов по имени Screen
и Window_mgr
.
Класс Screen
представляет окно на экране. У каждого объекта класса Screen
есть переменная-член типа string
, хранящая содержимое окна и три переменные-члена типа string::size_type
, представляющие позицию курсора, высоту и ширину окна.
Кроме переменных и функций-членов, класс может определять собственные локальные имена таких типов. Определенные классом имена типов подчиняются тем же правилам доступа, что и любой другой его член, и могут быть открытыми или закрытыми:
class Screen {
public:
typedef std::string::size_type pos;
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};
Тип pos
определен в части public
класса Screen
, поскольку пользователи должны использовать это имя. Пользователи класса Screen
не обязаны знать, что он использует класс string
для хранения своих данных. Определив тип pos
как открытый член, эту подробность реализации класса Screen можно скрыть.
В объявлении типа pos
есть два интересных момента. Во-первых, хоть здесь и был использован оператор typedef
(см. раздел 2.5.1), с таким же успехом можно использовать псевдоним типа (см. раздел 2.5.1):
class Screen {
public:
// альтернативный способ объявления типа-члена с использованием
// псевдонима типа
using pos = std::string::size_type;
// другие члены как прежде
};
Во-вторых, по причинам, которые будут описаны в разделе 7.3.4, в отличие от обычных членов, типы-члены определяются прежде, чем используются. В результате типы-члены обычно располагают в начале класса.
Screen
Чтобы сделать наш класс полезней, добавим в него конструктор, позволяющий пользователям задавать размер и содержимое экрана, наряду с членами, позволяющими переместить курсор и получить символ в указанной позиции:
class Screen {
public:
typedef std::string::size_type pos;
Screen() = default; // необходим, поскольку у класса Screen есть
// другой конструктор
// внутриклассовый инициализатор инициализирует курсор значением 0
Screen(pos ht, pos wd, char c) : height(ht), width(wd),
contents(ht * wd, c) { }
char get() const // получить символ в курсоре
{ return contents [cursor]; } // неявно встраиваемая
inline char get(pos ht, pos wd) const; // явно встраиваемая
Screen &move(pos r, pos с); // может быть сделана встраиваемой позже
private:
pos cursor = 0;
pos height = 0, width = 0;
std::string contents;
};
Поскольку мы предоставляем конструктор, компилятор не будет автоматически создавать стандартный конструктор сам. Если у нашего класса должен быть стандартный конструктор, то придется создать его явно. В данном случае используется синтаксис = default
, чтобы попросить компилятор самому создать определение стандартного конструктора (см. раздел 7.1.4).
Стоит также обратить внимание на то, что второй конструктор (получающий три аргумента) неявно использует внутриклассовый инициализатор для переменной-члена cursor
(см. раздел 7.1.4). Если бы у класса не было внутриклассового инициализатора для переменной-члена cursor
, то мы явно инициализировали бы ее наряду с другими переменными-членами.
У классов зачастую бывают небольшие функции, которые выгодно сделать встраиваемыми. Как уже упоминалось, определенные в классе функции-члены автоматически являются встраиваемыми ( inline
) (см. раздел 6.5.2). Таким образом, конструкторы класса Screen
и версия функции get()
, возвращающей обозначенный курсором символ, являются встраиваемыми по умолчанию.
Функцию-член можно объявить встраиваемой явно в ее объявлении в теле класса. В качестве альтернативы функцию можно указать встраиваемой в определении, расположенном вне тела класса:
inline // функцию можно указать встраиваемой в определении
Screen &Screen::move(pos r, pos с) {
pos row = r * width; // вычислить положение ряда
cursor = row + с; // переместить курсор к столбцу этого ряда
return *this; // возвратить этот объект как l-значение
}
char Screen::get(pos r, pos с) const // объявить встраиваемый в классе
{
pos row = r * width; // вычислить положение ряда
return contents[row + с]; // возвратить символ в данном столбце
Интервал:
Закладка: