|
Программирование >> Инициализация объектов класса, структура
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 не будет найдена, если только ее имени не предшествует оператор разрешения глобальной области видимости.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |