Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
print(cout, i, s, 42); // два параметра в пакете
Рекурсия выполнится следующим образом:
Вызов | t |
rest... |
---|---|---|
print(cout, i, s, 42) |
i |
s, 42 |
print(cout, s, 42) |
s |
42 |
Вызов print(cout, 42)
вызывает обычную версию функции print()
.
Первые два вызова могут соответствовать только версии функции print()
с переменным количеством аргументов, поскольку обычная версия не является подходящей. Эти вызовы передают четыре и три аргумента соответственно, а обычная функция print()
получает только два аргумента.
Для последнего вызова в рекурсии, print(cout, 42)
, подходят обе версии функции print()
. Этот вызов передает два аргумента, и типом первого являются ostream&
. Таким образом, подходящей является обычная версия функции print()
.
Версия с переменным количеством аргументов также является подходящей. В отличие от обычного аргумента, пакет параметров может быть пустым. Следовательно, экземпляр версии функции print()
с переменным количеством аргументов может быть создан только с двумя параметрами: один — для параметра ostream&
и другой — для параметра const T&
.
Обе функции обеспечивают одинаково хорошее соответствие для вызова. Однако нешаблонная версия с переменным количеством аргументов более специализирована, чем шаблонная с переменным количеством аргументов. Поэтому выбирается версия без переменного количества аргументов (см. раздел 16.3).
Объявление версии функции
print()
с постоянным количеством аргументов должно быть в области видимости, когда определяется версия с переменным количеством аргументов. В противном случае функция с переменным количеством аргументов будет рекурсивно вызывать себя бесконечно.
Упражнение 16.53. Напишите собственные версии функций print()
и проверьте их, выводя один, два и пять аргументов, у каждых из которых должны быть разные типы.
Упражнение 16.54. Что происходит при вызове функции print()
для типа, не имеющего оператора <<
?
Упражнение 16.55. Объясните, как выполнилась бы версия функции print()
с переменным количеством аргументов, если бы обычная версия функции print()
была объявлена после определения версии с переменным количеством аргументов.
16.4.2. Развертывание пакета
Кроме выяснения размера, единственное, что можно еще сделать с пакетом параметров, — это развернуть (pack expansion) его. При развертывании пакета предоставляется схема (pattern), используемая для каждого развернутого элемента. Развертывание пакета разделяет его на элементы с применением схемы к каждому из них. Для запуска развертывания справа от схемы помещают многоточие ( ...
).
Например, функция print()
содержит два развертывания:
template ostream &
print(ostream &os, const T &t, const Args&... rest) // развертывание
// Args
{
os << t << ", ";
return print(os, rest...); // развертывание rest
}
В первом случае развертывание пакета параметров шаблона создает список параметров функции print()
. Второй случай развертывания находится в вызове функции print()
. Эта схема создает список аргументов для вызова.
Развертывание пакета Args
применяет схему const Args&
к каждому элементу в пакете параметров шаблона Args
. Результатом этой схемы будет разделенный запятыми список из любого количества типов параметров в формате const тип &
. Например:
print(cout, i, s, 42); // два параметра в пакете
Типы последних двух аргументов, наряду со схемой, определяют типы замыкающих параметров. Этот вызов создает следующий экземпляр:
ostream&
print(ostream&, const int&, const strings, const int&);
Второе развертывание происходит в рекурсивном вызове функции print()
. В данном случае схема — это имя пакета параметров функции (т.е. rest
). Эта схема развертывается в разделяемый запятыми список элементов пакета. Таким образом, этот вызов эквивалентен следующему:
print(os, s, 42);
Развертывание пакета параметров функции print()
только разворачивало пакет на его составные части. При развертывании пакета параметров функции возможны и более сложные схемы. Например, можно было бы написать вторую функцию с переменным количеством аргументов, которая вызывает функцию debug_rep()
(см. раздел 16.3) для каждого из своих аргументов, а затем вызывает функцию print()
, чтобы вывести полученные строки:
// вызвать debug_rep() для каждого аргумента в вызове print()
template
ostream &errorMsg(ostream &os, const Args&... rest) {
// print(os, debug_rep(a1), debug_rep(a2), ..., debug_rep(an)
return print(os, debug_rep(rest)...);
}
Вызов функции print()
использует схему debug_rep(rest)
. Эта схема означает, что функцию debug_rep()
следует вызвать для каждого элемента в пакете параметров функции rest
. Получившийся развернутый пакет будет разделяемым запятыми списком вызовов функции debug_rep()
. Таким образом, вызов
errorMsg(cerr, fcnName, code.num(), otherData, "other", item);
выполняется, как будто было написано:
print(cerr, debug_rep(fcnName), debug_rep(code.num()),
debug_rep(otherData), debug_rep("otherData"),
debug_rep(item));
Следующая схема, напротив, не была бы откомпилирована:
// передает пакет debug_rep(); print(os, debug_rep(a1, a2, an))
print(os, debug_rep(rest...)); // ошибка: нет функции, соответствующей
// вызову
Проблема здесь в том, что пакет rest
развернут в вызове функции debug_rep()
. Этот вызов выполнился бы так, как будто было написано:
print(cerr, debug_rep(fcnName, code.num(),
otherData, "otherData", item));
В этом развертывании осуществляется попытка вызова функции debug_rep()
со списком из пяти аргументов. Нет никакой версии функции debug_rep()
, соответствующей этому вызову. Функция debug_rep()
имеет постоянное количество аргументов, и нет никакой ее версии с пятью параметрами.
Схема при развертывании применяется по отдельности к каждому элементу в пакете.
Упражнение 16.56. Напишите и проверьте версию функции errorMsg()
с переменным количеством аргументов.
Упражнение 16.57. Сравните свою версию функции errorMsg()
с переменным количеством аргументов с функцией error_msg()
из раздела 6.2.6. Каковы преимущества и недостатки каждого подхода?
Интервал:
Закладка: