|
Программирование >> Инициализация объектов класса, структура
class Screen { public: bkground относится к статическому члену, объявленному позже в определении класса ScreenS clear( char = bkground ); private: static const char bkground = #; Хотя такие аргументы в объявлениях функций-членов разрешаются во всей области видимости класса, программа будет считаться ошибочной, если он ссылается на нестатический член. Нестатический член должен быть привязан к объекту своего класса или к указателю на такой объект, иначе использовать его нельзя. Употребление подобных членов в качестве аргументов но умолчанию нарушает это ограничение. Если переписать class Screen { public: ... ошибка: bkground - нестатический член ScreenS clear( char = bkground ); private: const char bkground = #; предыдущий пример так: }; то имя аргумента по умолчанию разрешается нестатическим членом bkground, а это считается ошибкой. Определения членов класса, появляющиеся вне его тела, - это еще один пример части программы, которая находится в области видимости класса. В ней имена членов распознаются несмотря на то, что оператор доступа или оператор разрешения области видимости при обращении к ним не применяется. Как же разрешаются имена в определениях членов? Как правило, если такое определение появляется вне тела, то часть программы, следующая за именем определяемого члена, считается находящейся в области видимости класса вплоть до конца определения члена. Вынесем определение оператора class String { public: typedef int index type; charS operator[]( index type ); private: char * string; в operator[]() есть обращения к index type и string inline charS operator[]( index type elem ) { return string[ elem ]; operator[]() из класса String: class Account: ... private: static double interestRate; static double initInterestRate(); ссылается на Account::initInterest() операторов, ссылаться на члены класса: double Account:: interestRate = initInterest(); Инициализатор interestRate вызывает статическую функцию-член Account::initInterest() несмотря на то, что ее имя не квалифицировано именем класса. Не только инициализатор, но и все, что следует за именем статического члена interestRate до завершающей точки с запятой, находится в области видимости класса Account. Поэтому в определении статического члена name может быть обращение к class Account: ... private: static const int nameSize = 16; static const char name[nameSize]; nameSize не квалифицировано именем класса Account члену класса nameSize: const char Account::name[nameSize] = Savins Account ; Хотя член nameSize не квалифицирован именем класса Account, определение name не является ошибкой, так как оно находится в области видимости своего класса и может ссылаться на его члены после того, как компилятор прочитал Account::name. В определении члена, которое появляется вне тела, часть программы перед определяемым именем не находится в области видимости класса. При обращении к члену в этой части следует пользоваться оператором разрешения области видимости. Например, если типом статического члена является typedef Money, определенный в классе Account, то имя Money должно быть квалифицировано, когда статический член данных определяется вне тела класса: Обратите внимание, что в списке параметров встречается typedef index type без квалифицирующего имени класса String::.Текст, следующий за именем члена String::operator[] и до конца определения функции, находится в области видимости класса. Объявленные в этой области типы рассматриваются при разрешении имен типов, использованных в списке параметров функции-члена. Определения статических данных-членов также появляются вне определения класса. В них часть программы, следующая за именем статического члена вплоть до конца определения, считается находящейся в области видимости класса. Например, инициализатор статического члена может непосредственно, без соответствующих class Account { typedef double Money; ... private: static Money interestRate; static Money initInterest(); Money должно быть квалифицировано именем класса Account:: Account::Money Account:: interestRate = initInterest(); С каждым классом ассоциируется отдельная область видимости, причем у разных классов эти области различны. К членам одного класса нельзя напрямую обращаться в определениях членов другого класса, если только один из них не является для второго базовым. (Наследование и базовые классы рассматриваются в главах 17 и 18.) 13.9.1. Разрешение имен в области видимости класса Конечно, имена, используемые в области видимости класса, не обязаны быть именами членов класса. В процессе разрешения в этой области ведется поиск имен, объявленных и в других областях. Если имя, употребленное в области видимости класса, не разрешается именем члена класса, то компилятор ищет его в областях, включающих определение класса или члена. В этом подразделе мы покажем, как разрешаются имена, встречающиеся в области видимости класса. Имя, использованное внутри определения класса (за исключением определений встроенных функций-членов и аргументов но умолчанию), разрешается следующим образом: 1. Просматриваются объявления членов класса, появляющиеся перед употреблением имени. 2. Если на шаге 1 разрешение не привело к успеху, то просматриваются объявления в пространстве имен перед определением класса. Напомним, что глобальная область видимости - это тоже область видимости пространства имен. (О пространствах имен речь шла в разделе 8.5.) typedef double Money; class Account { ... private: static Money interestRate; static Money initInterest(); ... Например: Сначала компилятор ищет объявление Money в области видимости класса Account. При этом учитываются только те объявления, которые встречаются перед использованием Money. Поскольку таких объявлений нет, далее поиск ведется в глобальной области видимости. Объявление глобального typedef Money найдено, именно этот тип и используется в объявлениях interestRate и initInterest() .
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |