Упражнение 2.36. Определите в следующем коде тип каждой переменной и значения, которые будет иметь каждая из них по завершении.
>int а = 3, b = 4;
>decltype(а) с = а;
>decltype((b)) d = а;
>++c;
>++d;
Упражнение 2.37. Присвоение — это пример выражения, которое возвращает ссылочный тип. Тип — это ссылка на тип левого операнда. Таким образом, если переменная >i
имеет тип >int
, то выражение >i = x
имеет тип >int&
. С учетом этого определите тип и значение каждой переменной в следующем коде:
>int а = 3, b = 4;
>decltype(а) с = а;
>decltype(а = b) d = а;
Упражнение 2.38. Опишите различия выведения типа спецификаторами >decltype
и >auto
. Приведите пример выражения, где спецификаторы >auto
и >decltype
выведут тот же тип, и пример, где они выведут разные типы.
На самом простом уровне структура данных (data structure) — это способ группировки взаимосвязанных данных и стратегии их использования. Например, класс >Sales_item
группирует ISBN книги, количество проданных экземпляров и выручку от этой продажи. Он предоставляет также набор операций, таких как функция >isbn()
и операторы >>>
, ><<
, >+
и >+=
.
В языке С++ мы создаем собственные типы данных, определяя класс. Такие библиотечные типы, как >string
, >istream
и >ostream
, определены как классы, подобно типу >Sales_item
в главе 1. Поддержка классов в языке С++ весьма обширна, фактически части III и IV в значительной степени посвящены описанию средств, связанных с классами. Хотя класс >Sales_item
довольно прост, мы не сможем определить его полностью, пока не узнаем в главе 14, как писать собственные операторы.
>Sales_data
Несмотря на то что мы еще не можем написать свой класс >Sales_item
полностью, уже вполне можно создать достаточно реалистичный класс, группирующий необходимые элементы данных. Стратегия использования этого класса заключается в том, что пользователи будут получать доступ непосредственно к элементам данных и смогут самостоятельно реализовать необходимые операции.
Поскольку создаваемая структура данных не поддерживает операций, назовем новую версию >Sales_data
, чтобы отличать ее от типа >Sales_item
. Определим класс следующим образом:
>struct Sales_data {
> std::string bookNo;
> unsigned units_sold = 0;
> double revenue = 0.0;
>};
Класс начинается с ключевого слова >struct
, сопровождаемого именем класса и (возможно пустым) телом класса. Тело класса заключено в фигурные скобки и формирует новую область видимости (см. раздел 2.2.4). Определенные в классе имена должны быть уникальны в пределах класса, но вне класса они могут повторяться.
Ближайшие фигурные скобки, заключающие тело класса, следует сопроводить точкой с запятой. Точка с запятой необходима, так как после тела класса можно определить переменные:
>struct Sales_data { /* ... */ } accum, trans, *salesptr;
>// эквивалентно, но лучше определять эти объекты так
>struct Sales_data { /* ... */ };
>Sales data accum, trans, *salesptr;
Точка с запятой отмечает конец (обычно пустого) списка объявления операторов. Обычно определение объекта в составе определения класса — это не лучшая идея. Объединение в одном операторе определений двух разных сущностей (класса и переменной) ухудшает читабельность кода.