Следует заметить, что хотя определение типа Money в классе Account использует тот же тип, что и определение во внешней области видимости, этот код все же ошибочен.
Хотя переопределение имени типа является ошибкой, не все компиляторы обнаружат эту ошибку. Некоторые спокойно примут такой код, даже если программа ошибочна.
Поиск имени, используемого в теле функции-члена, осуществляется следующим образом.
• Сначала поиск объявления имени осуществляется в функции-члене. Как обычно, рассматриваются объявления в теле функции, только предшествующие месту использования имени.
• Если в функции-члене объявление не найдено, поиск продолжается в классе. Просматриваются все члены класса.
• Если объявление имени в классе не найдено, поиск продолжится в области видимости перед определением функции-члена.
Обычно не стоит использовать имя другого члена класса как имя параметра в функции-члене. Но для демонстрации поиска имени нарушим это правило в функции dummy_fcn():
//
//
//
int height; //
class Screen {
public:
typedef std::string::size_type pos;
void dummy_fcn(pos height) {
cursor = width * height; //
}
private:
pos cursor = 0;
pos height = 0, width = 0;
};
Когда компилятор обрабатывает выражение умножения в функции dummy_fcn(), он ищет имена сначала в пределах данной функции. Параметры функции находятся в области видимости функции. Таким образом, имя height, используемое в теле функции dummy_fcn(), принадлежит ее параметру.
В данном случае имя height параметра скрывает имя height переменной-члена класса. Если необходимо переопределить обычные правила поиска, то это можно сделать так:
//
//
void Screen::dummy_fcn(pos height) {
cursor = width * this->height; //
//
cursor = width * Screen::height; //
}
this.
Значительно проще обеспечить доступ к переменной-члену height, присвоив параметру другое имя:
//
//
void Screen::dummy_fcn(pos ht) {
cursor = width * height; //
}
Теперь, когда компилятор будет искать имя height, в функции dummy_fcn() он его не найдет. Затем компилятор просмотрит класс Screen. Поскольку имя height используется в функции-члене dummy_fcn(), компилятор просмотрит все объявления членов класса. Несмотря на то что объявление имени height расположено после места его использования в функции dummy_fcn(), компилятор решает, что оно относится к переменной-члену height.
Если компилятор не находит имя в функции или в области видимости класса, он ищет его в окружающей области видимости. В данном случае имя height объявлено во внешней области видимости, перед определением класса Screen. Однако объект во внешней области видимости скрывается переменной-членом класса по имени height. Если необходимо имя из внешней области видимости, к нему можно обратиться явно, используя оператор области видимости:
//
// определены в окружающих областях видимости