На самом простом уровне 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;
Точка с запятой отмечает конец (обычно пустого) списка объявления операторов. Обычно определение объекта в составе определения класса — это не лучшая идея. Объединение в одном операторе определений двух разных сущностей (класса и переменной) ухудшает читабельность кода.
В теле класса определены Sales_data.
Переменные-члены определяют точно так же, как и обычные переменные: указывается базовый тип, затем список из одного или нескольких операторов объявления. У нашего класса будут три переменные-члены: член типа string по имени bookNo, член типа unsigned по имени units_sold и член типа double по имени revenue. Эти три переменные-члены будут у каждого объекта класса Sales_data.
Sales_data переменные-члены units_sold и revenue будут инициализированы значением 0, а переменная-член bookNo — пустой строкой.
Внутриклассовые инициализаторы ограничены формой их использования (см. раздел 2.2.1): они должны либо быть заключены в фигурные скобки, либо следовать за знаком =. Нельзя определить внутриклассовый инициализатор в круглых скобках.
В разделе 7.2 указано, что язык С++ обладает еще одним ключевым словом, class, также используемым для определения собственной структуры данных. В этом разделе используем ключевое слово struct, поскольку пока еще не рассмотрены приведенные в главе 7 дополнительные средства, связанные с классом.
Упражнение 2.39. Откомпилируйте следующую программу и посмотрите, что будет, если не поставить точку с запятой после определения класса. Запомните полученное сообщение, чтобы узнать его в будущем.