На самом простом уровне 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. Откомпилируйте следующую программу и посмотрите, что будет, если не поставить точку с запятой после определения класса. Запомните полученное сообщение, чтобы узнать его в будущем.