Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
У некоторых библиотечных классов, включая уже использованные ранее, есть конструкторы с одним параметром.
• Конструктор класса string, получающий один параметр типа const char*(см. раздел 3.2.1), не является явным.
• Конструктор класса vector, получающий размер вектора (см. раздел 3.3.1), является явным.
Упражнение 7.47. Объясните, должен ли быть явным конструктор Sales_data(), получающий строку. Каковы преимущества объявления конструктора явным? Каковы недостатки?
Упражнение 7.48. С учетом того, что конструктор Sales_data()не является явным, какие операции происходят во время следующих определений:
string null_isbn("9-999-99999-9");
Sales_data item1(null_isbn);
Sales_data item2("9-999-99999-9");
Что будет при явном конструкторе Sales_data()?
Упражнение 7.49. Объясните по каждому из следующих трех объявлений функции combine(), что происходит при вызове i.combine(s), где i— это объект класса Sales_data, a s — строка:
(a) Sales_data &combine(Sales_data);
(b) Sales_data &combine(Sales_data&);
(c) Sales_data &combine(const Sales_data&) const;
Упражнение 7.50. Определите, должен ли какой-либо из конструкторов вашего класса Personбыть явным.
Упражнение 7.51. Как, по вашему, почему вектор определяет свой конструктор с одним аргументом как явный, а строка нет?
7.5.5. Агрегатные классы
Агрегатный класс (aggregate class) предоставляет пользователям прямой доступ к своим членам и имеет специальный синтаксис инициализации. Класс считается агрегатным в следующем случае.
• Все его переменные-члены являются открытыми ( public).
• Он не определяет конструкторы.
• У него нет никаких внутриклассовых инициализаторов (см. раздел 2.6.1).
• У него нет никаких базовых классов или виртуальных функций, связанных с классом средствами, которые рассматриваются в главе 15.
Например, следующий класс является агрегатным:
struct Data {
int ival;
string s;
};
Для инициализации переменных-членов агрегатного класса можно предоставить заключенный в фигурные скобки список инициализаторов для переменных-членов:
// val1.ival = 0; val1.s = string("Anna")
Data val1 = { 0, "Anna" };
Инициализаторы должны располагаться в порядке объявления переменных-членов. Таким образом, сначала располагается инициализатор для первой переменной-члена, затем для второй и т.д. Следующей пример ошибочен:
// ошибка: нельзя использовать "Anna" для инициализации ival или 1024
// для инициализации s
Data val2 = { "Anna" , 1024 };
Как и при инициализации элементов массива (см. раздел 3.5.1), если в списке инициализаторов меньше элементов, чем переменных-членов класса, последние переменные-члены инициализируются значением по умолчанию. Список инициализаторов не должен содержать больше элементов, чем переменных-членов у класса.
Следует заметить, что у явной инициализации переменных-членов объекта класса есть три существенных недостатка.
• Она требует, чтобы все переменные-члены были открытыми.
• Налагает дополнительные обязанности по правильной инициализации каждой переменной-члена каждого объекта на пользователя класса (а не на его автора). Такая инициализация утомительна и часто приводит к ошибкам, поскольку достаточно просто забыть инициализатор или предоставить неподходящее значение.
• Если добавляется или удаляется переменная-член, придется изменить все случаи инициализации.
Упражнение 7.52. На примере первой версии класса Sales_dataиз раздела 2.6.1 объясните следующую инициализацию. Найдите и исправьте возможные ошибки.
Sales_data item = {"978-0590353403", 25, 15.99};
7.5.6. Литеральные классы
В разделе 6.5.2 упоминалось, что параметры и возвращаемое значение функции constexprдолжны иметь литеральные типы. Кроме арифметических типов, ссылок и указателей, некоторые классы также являются литеральными типами. В отличие от других классов, у классов, являющихся литеральными типами, могут быть функции-члены constexpr. Такие функции-члены должны отвечать всем требованиям функций constexpr. Эти функции-члены неявно константные (см. раздел 7.1.2).
Агрегатный класс (см. раздел 7.5.5), все переменные-члены которого имеют литеральный тип, является литеральным классом. Неагрегатный класс, соответствующий следующим ограничениям, также является литеральным классом.
• У всех переменных-членов должен быть литеральный тип.
• У класса должен быть по крайней мере один конструктор constexpr.
• Если у переменной-члена есть внутриклассовый инициализатор, инициализатор для переменной-члена встроенного типа должен быть константным выражением (см. раздел 2.4.4). Если переменная-член имеет тип класса, инициализатор должен использовать его собственный конструктор constexpr.
• Класс должен использовать заданное по умолчанию определение для своего деструктора — функции-члена класса, удаляющего объекты типа класса (см. раздел 7.1.5).
constexprХотя конструкторы не могут быть константными (см. раздел 7.1.4), в литеральном классе они могут быть функциями constexpr(см. раздел 6.5.2). Действительно, литеральный класс должен предоставлять по крайней мере один конструктор constexpr.
Конструктор constexprможет быть объявлен как = default(см. раздел 7.1.4) или как удаленная функция, которые будут описаны в разделе 13.1.6. В противном случае конструктор constexprдолжен отвечать требованиям к конструкторам (у него не может быть оператора return) и к функциям constexpr(его исполняемый оператор может иметь единственный оператор return) (см. раздел 6.5.2). В результате тело конструктора constexprобычно пусто. Определению конструктора constexprпредшествует ключевое слово constexpr:
class Debug {
public:
constexpr Debug(bool b = true): hw(b), io(b), other(b) { }
constexpr Debug(bool h, bool i, bool o):
hw(h), io(i), other(o) { }
constexpr bool any() { return hw || io || other; }
void set_io(bool b) { io = b; }
void set_hw(bool b) { hw = b; }
void set_other(bool b) { hw = b; }
private:
bool hw; // аппаратная ошибка, отличная от ошибки IO
bool io; // ошибка IO
bool other; // другие ошибки
};
Конструктор constexprдолжен инициализировать каждую переменную-член. Инициализаторы должны либо использовать конструктор constexpr, либо быть константным выражением.
Интервал:
Закладка: