|
Программирование >> Инициализация объектов класса, структура
class List { public: ... private: class ListItem { public: ошибка: нет видимого объявления для ::list void check status() { int value = ::lis; } ... ListItem *list; ... int list = 0; Глобальн1й объект list объявлен после определения класса List. Во встроенной функции-члене, определенной внутри тела класса, рассматриваются только те глобальные объявления, которые были видны перед определением объемлющего класса. Если же определение check status() следует за определением List, то рассматриваются глобальные объявления, расположенные перед ним, поэтому будет найдено глобальное определение объекта list. Упражнение 13.21 В главе 11 был приведен пример программы, использующей класс iStack. Измените его, объявив классы исключений pushOnFull и popOnEmpty открытыми вложенн1ми в iStack. Модифицируйте соответствующим образом определение класса iStack и его функций-членов, а также определение main() . 13.11. Классы как члены пространства имен A Представленные до сих пор классы определены в области видимости глобального пространства имен. Но их можно определять и в объявленных пользователем пространствах. Имя класса, определенного таким образом, доступно только в области видимости этого пространства, т. е. оно не конфликтует с именами, объявленными в namespace cplusplus primer { class Node { /* Т.. */ }; namespace DisneyFeatureAnimation { class Node { /* ... */ }; Node *pnode; ошибка: Node не видно в глобальной области видимости правильно: объявляет nodeObj как объект квалифицированного типа DisneyFeatureAnimation::Node DisneyFeatureAnimation::Node nodeObj; using-объявление делает Node видим в глобальной области видимости using cplusplus primer::Node; других пространствах имен. Например: Node another; cplusplus primer::Node --- primer.h ---namespace cplusplus primer { class List { ... private: class ListItem { public: void check status(); int action(); ... --- primer.C --- #include primer.h namespace cplusplus primer { правильно: check status() определено в том же пространстве имен, что и List void List::ListItem::check status() { } правильно: action() определена в глобальной области видимости в пространстве имен, объемлющем определение класса List / / Имя члена квафицировано именем пространства возможность организовать код библиотеки следующим образом: int cplusplus primer::List::ListItem::action() { } Члены вложенного класса ListItem можно определить в пространстве имен cplusplus primer, которое содержит определение List, или в глобальном пространстве, включающем определение cplusplus primer. В любом случае имя члена в определении должно быть квалифицировано именами объемлющих классов и объявленных пользователем пространств, вне которых находится объявление члена. Как происходит разрешение имени в определении члена, которое находится в int cplusplus primer::List::ListItem::action() { int local = someVal; ... объявленном пользователем пространстве? Например, как будет разрешено someVal: Сначала просматриваются локальные области видимости в определении функции-члена, затем поиск продолжается в области видимости ListItem, затем - в области видимости List. До этого момента все происходит так же, как в процессе разрешения имен, описанном в разделе 13.10. Далее просматриваются объявления из пространства cplusplus primer и наконец объявления в глобальной области видимости, причем во Как было показано в двух нред1дущих разделах, член класса (функция-член, статический член или вложенный класс) может быть определен вне его тела. Если м1 реализуем библиотеку и помещаем определения наших классов в объявленное пользователем пространство имен, то где расположить определения членов, находящиеся вне тел своих классов? Их можно разместить либо в пространстве имен, которое содержит определение самого внешнего класса, либо в одном из объемлющих его пространств. Это дает --- primer.h --namespace cplusplus primer { class List { ... private: class ListItem { public: int action(); ... const int someVal = 365; --- primer.C --- a1m,a a и 11 #include primer.h namespace cplusplus primer { int List::ListItem::action() { правильно: cplusplus primer::someVal int local = someVal; ошибка: calc() еще не объявлена double result = calc( local ); ... double calc(int) { } ... action() : Определение пространства имен cplusplus primer не является непрерывным. Определения класса List и объекта someVal размещены в первом его разделе, который находится в заголовочном файле primer.h. Определение функции calc() появляется в определении пространства имен, расположенном в файле реализации primer.C. Использование calc() внутри action() ошибочно, так как она объявлена после использования. Если calc() - часть интерфейса cplusplus primer, ее следовало бы --- primer.h --namespace cplusplus primer { class List { ... const int someVal = 365; double calc(int); объявить в той части данного пространства, которая находится в заголовочном файле: Если же calc() используется только в action() и не является частью интерфейса пространства имен, то ее нужно объявить перед action() , чтобы можно было ссылаться на нее внутри определения action() . внимание принимаются только те, которые расположены до определения функции-члена
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |