Министерство цифровых информационных технологий и коммуникаций республики узбекистан каршинский филиал ташкентского университета информационных технологий


Download 98.86 Kb.
bet10/11
Sana18.11.2023
Hajmi98.86 Kb.
#1785551
TuriСамостоятельная работа
1   2   3   4   5   6   7   8   9   10   11
Bog'liq
5-mus

namespace N {/* ... */}
// ...
N::Foo();
В этом случае первоначальной текущей областью видимости будет пространство имен N, переход в объемлющие области вообще не выполняется.
::Foo();
В этом случае первоначальной текущей областью видимости будет глобальное пространство имен, объемлющих областей видимости нет.
Рассмотрим теперь «голые» вызовы функций без дополнительных квалификаторов класса или пространства имен.
Если такой вызов находится в пространстве имен, то это пространство имен и будет первоначальной текущей областью видимости, объемлющими областями видимости будут объемлющие пространства имен.
Если такой вызов находится в пространстве имен класса (например при инициализации статического члена), то соответствующий класс будет первоначальной текущей областью видимости, объемлющими областями видимости будут базовые классы и далее объемлющие пространства имен.
Пусть такой вызов находится в блоке
{
Foo();
}
В этом случае первоначальной текущей областью видимости будет этот блок. (Напомним, что возможны локальные объявления функций, подробнее см. далее.) Объемлющими областями видимости будут объемлющие блоки, далее класс (если блок находится в функции-члене) и далее объемлющие пространства имен.
Разрешение перегрузки в классах
Рассмотрим пример.
class B
{
// ...
public:
void Foo(int x);
};


class D : public B
{
// ...
public:
D();
void Foo(double x);
};
// ...
D d;
d.Foo(42);
Какая из двух доступных Foo, будет выбрана? Правильный ответ D::Foo(double), хотя B::Foo(int) подходит лучше и доступна в точке вызова. Поиск начинается с текущей области видимости (в данном случае класс D), найдена функция с соответствующим именем, объемлющая область видимости (в данном случае класс B) не рассматривается. Единственная найденная функция D::Foo(double) может быть вызвана с данным аргументом и разрешение перегрузки завершается успешно. Если бы D::Foo(double) была бы объявлена закрытой или защищенной или удаленной, то компиляция завершилась бы ошибкой, но B::Foo(int) все равно бы не рассматривалась, хотя она и доступна в точке вызова. И только, если из класса D совсем убрать Foo, то компилятор сделал бы текущей областью видимости класс B и выбрал бы B::Foo(int).
Эти правила могут оказаться достаточно неожиданными для программиста. Наследование в C++ спроектировано так, чтобы сделать границу между производным и базовым классом максимально прозрачной, а в данном случае такой прозрачности нет. При неблагоприятных условиях это может привести к трудно обнаруживаемым ошибкам. Например, можно получить бесконечную рекурсию. (Но это еще не худший вариант, такая ошибка сразу обнаружится при выполнении.)

Локальное объявление функций


Рассмотрим теперь одну редко используемую особенность C++, которая называется локальные объявления функций. Функции можно объявлять локально (в блоке), например:
{

Download 98.86 Kb.

Do'stlaringiz bilan baham:
1   2   3   4   5   6   7   8   9   10   11




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling