Страница 2 из 48
Класс. Объявление класса Класс - это тип. Этот производный тип вводится в программу с помощью специального оператора объявления класса. В объявлении класса используется ранее описанный инструментальный набор средств для построения и преобразования производных типов. Очередное множество форм Бэкуса-Наура определяет синтаксис объявления класса. Объявление ::= [СписокСпецификаторовОбъявления] [СписокОписателей]; СписокСпецификаторовОбъявления ::= [СписокСпецификаторовОбъявления] СпецификаторОбъявления СпецификаторОбъявления ::= СпецификаторТипа ::= ***** СпецификаторТипа ::= СпецификаторКласса ::= УточнённыйСпецификаторТипа ::= ***** УточнённыйСпецификаторТипа ::= КлючевоеСловоКласса ИмяКласса ::= КлючевоеСловоКласса Идентификатор ::= enum ИмяПеречисления КлючевоеСловоКласса ::= union ::= struct ::= class ИмяКласса ::= Идентификатор СпецификаторКласса ::= ЗаголовокКласса {[СписокЧленов]} ЗаголовокКласса ::= КлючевоеСловоКласса [Идентификатор] [СпецификацияБазы] ::= КлючевоеСловоКласса ИмяКласса [СпецификацияБазы] КлючевоеСловоКласса ::= union ::= struct ::= class ИмяКласса ::= Идентификатор
Спецификатор класса представляет то, что называется объявлением класса. Уточнённый спецификатор типа объявляет расположенный за ним идентификатор именем класса. Уточнённый спецификатор обеспечивает неполное предварительное объявление класса и перечисления. Назначение и смысл необязательного нетерминального символа СпецификацияБазы будут обсуждаться позже, в разделах, посвящённых наследованию. Предварительное объявление обеспечивается уточнённым спецификатором типа и является своеобразным прототипом класса или перечисления. Его назначение - сообщение транслятору предварительной информации о том, что существует (должно существовать) объявление класса (или перечисления) с таким именем. Идентификатор, используемый в контексте уточнённого спецификатора имени становится именем класса (или именем перечисления). Класс считается объявленным даже тогда, когда в нём полностью отсутствует информация о членах класса (пустой список членов класса). Неименованный класс с пустым множеством членов - уже класс! Имя класса можно употреблять как имя (имя типа) уже в списке членов этого самого класса. Класс может быть безымянным. Следующая последовательность операторов объявления class {}; /* Объявлен пустой неименованный класс.*/ class {}; class {}; class {}; /* Это всё объявления. Их количество ничем не ограничивается. */ struct {}; /* Структура - это класс, объявленный с ключевым словом struct. Опять же пустой и неименованный.*/
не вызывает у транслятора никаких возражений. На основе класса, пусть даже неименованного, может быть объявлен (вернее, определён) объект-представитель этого класса. В таком контексте объявление неименованного (пусть даже и пустого!) класса является спецификатором объявления. Имена определяемых объектов (возможно с инициализаторами) составляют список описателей. class {} Obj1, Obj2, Obj3;/* Здесь объявление пустого класса.*/ class {} Obj4, Obj5, Obj6;/* Просто нечего инициализировать.*/ class {} Obj1; /* ^ Ошибка. Одноименные объекты в области действия имени.*/
Неименованные классы также можно применять в сочетании со спецификатором typedef (здесь может быть объявление класса любой сложности - не обязательно только пустой). Спецификатор typedef вводит новое имя для обозначения безымянного класса. Описанное имя типа становится его единственным именем. Сочетание спецификатора typedef с объявлением безымянного класса подобно объявлению класса с именем: class MyClass {/*…*/}; typedef class {/*…*/} MyClass;
Правда в первом случае класс имеет собственное имя класса, а во втором - описанное имя типа. Использование описанного имени типа в пределах области действия имени делает эквивалентными следующие определения (и им подобные): class {} Obj1; MyClass Obj1;
Класс считается объявленным лишь после того, как в его объявлении будет закрыта последняя фигурная скобка. До этого торжественного момента информация о структуре класса остаётся неполной. Если можно ОБЪЯВИТЬ пустой класс, то можно ОПРЕДЕЛИТЬ и объект-представитель пустого класса. Эти объекты размещаются в памяти. Их размещение предполагает выделение объекту участка памяти с уникальным адресом, а это означает, что объекты пустого класса имеют ненулевой размер. Действительно, значения выражений sizeof(MyClass) и sizeof(MyObj1) (это можно очень просто проверить) отличны от нуля. А вот пустое объединение (ещё одна разновидность класса - класс, объявленный с ключевым словом union) не объявляется: union {}; /* Некорректное объявление объединения. */ При объявлении объединения требуется детальная информация о внутреннем устройстве этого объединения. |