Министерство цифровых информационных технологий и коммуникаций республики узбекистан каршинский филиал ташкентского университета информационных технологий
Download 98.86 Kb.
|
5-mus
- Bu sahifa navigatsiya:
- Разрешение перегрузки в классах Рассмотрим пример. class B { // ... public : void Foo (int
- Локальное объявление функций
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: |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling