Программирование >>  Инициализация объектов класса, структура 

1 ... 215 216 217 [ 218 ] 219 220 221 ... 395


namespace LibException class pushCnFull{ }; class popCnEmpty{ };

исключений pushCnFull и popCnEmpty как члены пространства имен LibException:

а сам iStack - членом пространства имен Container. Модифицируйте соответствующим образом определение данного класса и его функций-членов, а также определение main() .

Здесь прослеживается аналогия с процессом поиска объявлений в глобальной области видимости, о котором мы говорили в предыдущих разделах: объявления, предшествующие определению члена, принимаются во внимание, тогда как следующие за ним игнорируются.

Довольно просто запомнить, в каком порядке просматриваются области видимости при поиске имени из определения функции, расположенного вне определения класса. Имена, которыми квалифицировано имя члена, указывают порядок рассмотрения пространств. Например, имя action() в предыдущем примере квалифицируется так:

cplusplus primer::List::ListItem::action()

Квалификаторы cplusplus primer::List::ListItem:: записаны в порядке, обратном тому, в котором просматриваются имена областей видимости классов и пространств имен. Сначала поиск ведется в области ListItem, затем продолжается в объемлющем классе List и наконец в пространстве cplusplus primer, предшествующем той области, в которой находится определение action() . Во время поиска в любой области видимости класса просматриваются все объявления членов, а в любом пространстве имен - только те объявления, которые встречались перед определением члена.

Класс, определенный в области видимости пространства имен, потенциально виден во всей программе. Если заголовочный файл primer.h включен в несколько исходных файлов, то имя cplusplus primer::List везде относится к одному и тому же классу. Класс - это сущность, для которой в программе может быть более одного определения. Определение класса должно присутствовать один раз в каждом исходном файле, где определяются или используются сам класс или его члены. Однако оно должно быть одинаковым во всех файлах, где встречается, поэтому его следует помещать в заголовочный файл, например primer.h. Затем такой файл можно включать в любой исходный, где определяются или используются члены класса. Это предотвратит несоответствия в случае, когда определение класса записывается более одного раза.

Невстроенные функции-члены и статические данные-члены класса в пространстве имен -это также программные сущности. Однако они могут быть определены лишь один раз во всей программе. Поэтому их определения помещаются не в заголовочный, а в отдельный исходный файл типа primer.C.

Упражнение 13.22

Используя класс iStack, определенный в упражнении 13.21, объявите классы



void foo( int val ) {

class Bar { public:

int barVal;

class nested; объявление вложенного класса обязательно

определение вложенного класса class Bar::nexted {

...

объемлющего класса. Объявление вложенного класса в объемлющем нельзя опускать:

У объемлющей функции нет никаких специальных прав доступа к закрыт1м членам локального класса. Разумеется, это можно обойти, объявив ее другом данного класса. Однако необходимость делать его члены закрытыми вообще сомнительна, поскольку часть программы, из которой разрешается обратиться к нему, весьма ограничена. Локальный класс инкапсулирован в своей локальной области видимости. Дальнейшая инкапсуляция путем сокрытия информации не требуется: вряд ли на практике найдется причина, по которой не все члены локального класса должны быть открыты.

У локального класса, как и у вложенного, ограничен доступ к именам из объемлющей области видимости. Он может обратиться только к именам типов, статических переменных и элементов перечислений, определенных в объемлющих локальных областях. Например:

13.12. Локальные классы A

Класс, определенный внутри тела функции, называется локальным. Он виден только в той локальной области, где определен. Не существует синтаксиса, позволяющего обратиться к члену такого класса, в отличие от вложенного, извне локальной области видимости, содержащей его определение. Поэтому функции-члены локального класса должны определяться внутри определения самого класса. На практике это ограничивает их сложность несколькими строками кода; помимо всего прочего, такой код становится трудно читать.

Поскольку невозможно определить член локального класса в области видимости пространства имен, то в таком классе не бывает статических членов.

Класс, вложенный в локальный, может быть определен вне определения объемлющего класса, но только в локальной области видимости, содержащей это определение. Имя вложенного класса в таком определении должно быть квалифицировано именем



int a, val;

void foo( int

val )

= 1024, b };

static int si; enum Loc { a = class Bar { public:

Loc locVal; правильно

int barVal;

void fooBar

barVal =

barVal = ::val; barVal = si-

1 oAfo 1

( Loc l = a

val;

= si;

locVal = b;

правильно: Loc::a ошибка: локальн объект правильно: глобальн объект правильно: статический локальн объект правильно: элемент перечисления

Имена в теле локального класса разрешаются лексически путем поиска в объемлющих областях видимости объявлений, предшествующих определению такого класса. При разрешении имен, встречающихся в телах его функций-членов, сначала просматривается область видимости класса, а только потом - объемлющие области,

Как всегда, если первое найденное объявление таково, что употребление имени оказывается некорректным, поиск других объявлений не производится. Несмотря на то что использование val в fooBar() выше является ошибкой, глобальная переменная val не будет найдена, если только ее имени не предшествует оператор разрешения глобальной области видимости.



1 ... 215 216 217 [ 218 ] 219 220 221 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика