Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Справочное руководство по C++.doc
Скачиваний:
0
Добавлен:
03.01.2020
Размер:
2.03 Mб
Скачать

R.9 классы

Класс есть тип. Его имя используется как имя-класса ($$R.9.1), т.е.

становится зарезервированным словом в его области видимости.

имя-класса:

идентификатор

Для образования конструкции имя-класса используются спецификации-класса

и спецификации-сложного-типа ($$R.7.1.6). Объект класса состоит из

последовательности (возможно пустой) членов.

спецификация-класса:

заголовок-класса { список-членов opt }

заголовок-класса:

служебное-слово-класса идентификатор opt спец-базовых opt

служебное-слово-класса имя-класса спец-базовых opt

служебное-слово-класса:

class

struct

union

Имя класса можно использовать в качестве конструкции имя-класса

даже в списке-членов самого этого класса. Обычно спецификацию-класса

называют описанием класса. Класс считается определенным, как только

появится спецификация-класса, несмотря на то, что его функции-члены

могут быть еще неопределены.

Объекты пустого класса имеют ненулевой размер.

Объекты типа класс можно присваивать, передавать в качестве

параметров функций и получать в качестве значения, возвращаемого

функцией (за исключением объектов тех классов, для которых копирование

ограничено, см. $$R.12.8). Другие возможные операции, такие, как

сравнение на равенство, могут определяться пользователем, см. $$R.13.4.

Структурой называется класс, описанный со служебным-словом-класса

struct; ее члены и базовые классы ($$R.10) считаются общими по

определению ($$R.11). Объединением называется класс, описанный со

служебным-словом-класса union; его члены считаются общими по

определению, и в любой момент времени объединение содержит только

один член ($$R.9.5).

R.9.1 Имена класса

Описание класса порождает новый тип. Например, ниже описываются

три переменные трех различных типов:

struct X { int a; };

struct Y { int a; };

X a1;

Y a2;

int a3;

Отсюда следует, что такие присваивания приводят к несоответствию

типов:

a1 = a2; // ошибка: Y присваивается X

a1 = a3; // ошибка: int присваивается X

Ниже описывается перегрузка ($$R.13) функции f(), а не просто

повторное описание той же функции:

int f(X);

int f(Y);

По той же причине нельзя дважды определять класс, это видно из

примера ниже, где дважды определен S:

struct S { int a; };

struct S { int a; }; // ошибка, повторное определение

Описание класса включает имя класса в ту область видимости, внутри

которой оно произошло, и закрывает любой класс, объект, функцию или

другое описание этого имени в объемлющей области видимости ($$R.3.2).

Если имя класса описано в такой области видимости, где уже был

описан объект с таким же именем, функция или элемент перечисления, то

обращаться к классу можно только с помощью конструкции

спецификация-сложного-типа ($$R.7.1.6), например:

struct stat {

// ...

};

stat gstt; // просто `stat' используется для

// определения переменной

int stat(struct stat*); // переопределение `stat' как функции

void f()

{

struct stat* ps; // нужен префикс struct

// для задания структуры stat

// ...

stat(ps); // вызов stat()

// ...

}

Конструкция спецификация-сложного-типа вместе со

служебным-словом-класса, но без описания объекта или функции также

может служить для задания имени класса, как и описание класса, однако

в этом случае класс не считается определенным, например:

struct s { int a; };

void g()

{

struct s; // скрывает глобальную структуру `s'

s* p; // используется локальная структура `s'

struct s { char* p; }; // описание локальной структуры `s'

}

Такие правила позволяют классам ссылаться друг на друга при их

описании, пример,

class vector;

class matrix {

// ...

friend vector operator*(matrix&, vector&);

};

class vector {

// ...

friend vector operator*(matrix&, vector&);

};

Описание friend (дружественные функции) обсуждается в $$R.11.4, а

функция operator в $$R.13.4. Если класс, указанный как друг, пока

еще не описан, его имя считается принадлежащим той же области

видимости, в которой находится имя класса, содержащего описание

friend ($$R.11.4).

В описании объектов или функций можно также использовать

конструкцию спецификация-сложного-типа ($$R.7.1.6). Ее использование

отличается от описания класса тем, что если класс, чье имя указано

в спецификации, находится в текущей области видимости, то имя из

этой спецификации будет ссылаться на него, например:

struct s { int a; }

void g()

{

struct* s p = new s; // обращение к глобальной `s'

p->a = 1;

}

Имя считается описанным сразу же после появления его идентификатора

в описании. Отсюда следует, что в описании

class A * A;

A в начале задается, как имя класса, а затем оно переопределяется

как имя указателя на объект этого класса, поэтому для обозначения этого

класса следует использовать спецификацию-сложного типа class A. Такое

"трюкачество" с именами может вызвать недоумение, и лучше его избегать.

Конструкция имя-typedef ($$R.7.1.3) обозначает класс и считается

именем-класса, см. также $$R.7.1.3.