Область видимости в C ++

Scope C



Сущность в C ++ имеет имя, которое можно объявить и / или определить. Объявление - это определение, но определение не обязательно является декларацией. Определение выделяет память для названного объекта, но объявление может или не может выделять память для названного объекта. Декларативная область - это самая большая часть программы, в которой допустимо имя объекта (переменной). Эта область называется областью действия или потенциальной областью действия. В этой статье объясняется область видимости в C ++. Кроме того, для понимания этой статьи необходимы базовые знания C ++.

Содержание статьи

Декларативный регион и объем

Декларативная область - это самая большая часть текста программы, в которой допустимо имя объекта. Это регион, в котором неквалифицированное имя может использоваться (отображаться) для обозначения одного и того же объекта. Рассмотрим следующую короткую программу:







#включают
с использованием пространство именчасы;

пустотаfn()
{
intкудазнак равно 3;
если (1==1)
{
Стоимость<<куда<<' п';
}
}

intглавный()
{
fn();
возвращение 0;
}

Функция fn () имеет два блока: внутренний блок для условия if и внешний блок для тела функции. Идентификатор var вводится и отображается во внешнем блоке. Это также видно во внутреннем блоке с оператором cout. Внешний и внутренний блоки являются областью для имени var.



Однако имя var по-прежнему можно использовать для объявления другой сущности, такой как float, во внутреннем блоке. Следующий код иллюстрирует это:



#включают
с использованием пространство именчасы;

пустотаfn()
{
intкудазнак равно 3;
если (1==1)
{
плаватькудазнак равно 7,5;
Стоимость<<куда<<' п';
}
}

intглавный()
{
fn();
возвращение 0;
}

Выход 7,5. В этом случае имя var больше не может использоваться во внутреннем блоке для ссылки на целое число значения 3, которое было введено (объявлено) во внешнем блоке. Такие внутренние блоки называются потенциальной областью для сущностей, объявленных во внешнем блоке.





Примечание. Сущность того же типа, что и внешний блок, все еще может быть объявлена ​​во внутреннем блоке. Однако в этом случае во внутреннем блоке допустимо новое объявление и его значение, в то время как старое объявление и его значение вне внутреннего блока остаются действительными во внешнем блоке.

Объявление с тем же именем во внутреннем блоке обычно отменяет объявление с тем же именем вне этого внутреннего блока. Во внутренние блоки могут вкладываться другие внутренние блоки.



Глобальный масштаб

Когда программист только начинает печатать файл, это глобальная область видимости. Следующая короткая программа иллюстрирует это:

#включают
с использованием пространство именчасы;

плаватькудазнак равно 9,4;

intглавный()
{
Стоимость <<куда<<' п';
Стоимость <<::куда<<' п';

возвращение 0;
}

Результат:
9,4
9,4

В этом случае декларативная область или область видимости для var начинается с точки объявления для var, продолжается вниз до конца файла (единицы трансляции).

Блок функции main () имеет другую область видимости; это вложенная область видимости для глобальной области видимости. Чтобы получить доступ к объекту глобальной области видимости из другой области, идентификатор используется непосредственно или предшествует оператору разрешения области видимости, ::.

Примечание. Сущность main () также объявлена ​​в глобальной области видимости.

Область действия блока

Каждый оператор if, while, do, for или switch может определять блок. Такое утверждение является составным утверждением. Имя переменной, объявленной в блоке, имеет область действия блока. Его область действия начинается в точке объявления и заканчивается в конце блока. Следующая короткая программа иллюстрирует это для переменной идент:

#включают
с использованием пространство именчасы;

intглавный()
{
если (1==1)
{
/ * некоторые утверждения * /
intИдентификаторзнак равно 5;
Стоимость<<Идентификатор<<' п';
/ * некоторые утверждения * /
}
возвращение 0;
}

Переменная, такая как идентификатор, объявленная в области видимости блока, является локальной переменной.

Переменная, объявленная вне области видимости блока и выше, может быть видна в заголовке блока (например, в условии для блока if), а также внутри блока. Следующая короткая программа иллюстрирует это для переменной identif:

#включают
с использованием пространство именчасы;

intглавный()
{
intидентифицироватьзнак равно 8;

если (идентифицировать== 8)
{
Стоимость<<идентифицировать<<' п';
}
возвращение 0;
}

Результатом будет 8. Здесь есть две области видимости блока: блок для функции main () и вложенный оператор if-complex. Вложенный блок является потенциальной областью функционального блока main ().

Объявление, введенное в области видимости блока, не может быть видно за пределами блока. Следующая короткая программа, которая не компилируется, иллюстрирует это с помощью переменной variab:

#включают
с использованием пространство именчасы;

intглавный()
{
если (1 == 1)
{
intпеременнаязнак равно пятнадцать;
}
Стоимость<<переменная<<' п'; // ошибка: доступ за пределами области действия.

возвращение 0;
}

Компилятор выдает сообщение об ошибке для переменной.

Введенная сущность, объявленная в заголовке составной функции, не может быть видна вне (ниже) составного оператора. Следующий код цикла for не будет компилироваться, что приведет к сообщению об ошибке:

#включают
с использованием пространство именчасы;

intглавный()
{
для (intязнак равно0;я<4; ++я)
{
Стоимость<<я<<'';
}
Стоимость<<я<<'';

возвращение 0;
}

Переменная итерации i видна внутри блока цикла for, но не вне блока цикла for.

Объем функции

Функциональный параметр отображается в функциональном блоке. Сущность, объявленная в функциональном блоке, видна от точки объявления до конца функционального блока. Следующая короткая программа иллюстрирует это:

#включают
#включают
с использованием пространство именчасы;

строка fn(строка str)
{
charполоса[] знак равно 'бананы';
/ * другие операторы * /
строка totalStrзнак равноп+полоса;
возвращениеtotalStr;
}

intглавный()
{
строка totStrзнак равноfn('принимать пищу ');
Стоимость<<totStr<<' п';

возвращение 0;
}

Результат:
есть бананы

Примечание. Сущность, объявленную вне функции (над ней), можно увидеть в списке параметров функции, а также в функциональном блоке.

Этикетка

Объем метки - это функция, в которой она появляется. Следующий код иллюстрирует это:

#включают
с использованием пространство именчасы;

пустотаfn()
{
перейти клабл;
/ * другие операторы * /
лабл: intнетзнак равно 2;
Стоимость<<нет<<' п';
}

intглавный()
{
fn();

возвращение 0;
}

Выход 2.

Область перечисления

Перечисление без области видимости
Рассмотрим следующий if-блок:

если (1==1)
{
перечислить {а, б, взнак равноб+2};
Стоимость<<к<<''<<б<<''<<c<<' п';
}

На выходе 0 1 3.

Первая строка в блоке - это перечисление, a, b и c - его перечислители. Область действия перечислителя начинается с точки объявления до конца включающего блока перечисления.

Следующий оператор не будет компилироваться, потому что точка объявления c находится после точки объявления a:

перечислить {кзнак равноc+2, до н.э};

Следующий сегмент кода не будет компилироваться, поскольку доступ к перечислителям осуществляется после включающего блока перечисления:

если (1==1)
{
перечислить {а, б, взнак равноб+2};
}
Стоимость<<к<<''<<б<<''<<c<<' п'; // ошибка: вне области видимости

Вышеупомянутое перечисление описывается как перечисление без области действия, а его перечислители описываются как перечислители без области действия. Это потому, что он начинается только с зарезервированного слова enum. Перечисления, которые начинаются с класса перечисления или структуры перечисления, описываются как перечисления с ограниченной областью действия. Их счетчики описываются как счетчики с заданной областью действия.

Перечисление с ограничением
Следующее утверждение в порядке:

перечислить классмужчина{а, б, взнак равноб+2};

Это пример перечисления с ограниченной областью видимости. Имя класса - nam. Здесь область действия перечислителя начинается с точки объявления до конца определения перечисления, а не от конца включающего блока для перечисления. Следующий код не будет компилироваться:

если (1==1)
{
перечислить классмужчина{а, б, взнак равноб+2};
Стоимость<<к<<''<<б<<''<<c<<' п'; // ошибка: выходит за рамки класса перечисления или структуры перечисления
}

Область действия класса

При нормальной области действия декларативная область начинается с точки, затем продолжается и останавливается в другой точке. Область существует в одной непрерывной области. С помощью класса область действия объекта может находиться в разных регионах, которые не соединены вместе. Правила для вложенных блоков по-прежнему применяются. Следующая программа иллюстрирует это:

#включают
с использованием пространство именчасы;

// Базовый класс
классCla
{
частный:
intmemPзнак равно 5;
защищенный:
intmemProзнак равно 9;
общественный:
пустотаfn()
{
Стоимость<<memP<<' п';
}
};

// Производный класс
классDerCla: общественныйCla
{
общественный:
intderMemзнак равноmemPro;
};
intглавный()
{
Cla obj;
объектfn();
DerCla derObj;
Стоимость<<derObj.derMem<<' п';

возвращение 0;
}

Результат:
5
9

В классе Cla переменная memP видна в точке объявления. После этого короткая часть protected пропускается, а затем снова отображается в функциональном блоке-члене класса. Производный класс пропускается, а затем снова отображается в области (блоке) функции main ().

В классе Cla переменная memPro видна в точке объявления. Часть общедоступной функции fn () пропускается, а затем отображается в блоке описания производного класса. Это снова видно в функции main ().

Оператор разрешения области видимости
Оператор разрешения области видимости в C ++ - ::. Он используется для доступа к статическому члену класса. Следующая программа иллюстрирует это:

#включают
с использованием пространство именчасы;

классCla
{
общественный:
статический int constмемзнак равно 5;
общественный:
статический пустотаfn()
{
Стоимость<<мем<<' п';
}
};
intглавный()
{
Стоимость<<Cla::мем<<' п';
Cla::fn();

возвращение 0;
}

Результат:
5
5

Статические члены видны в функциональном блоке main (), доступ к которому осуществляется с помощью оператора разрешения области видимости.

Область действия параметра шаблона

Обычная область действия имени параметра шаблона начинается с момента объявления до конца его блока, как в следующем коде:

шаблон<typenameТ,typenameU> структураВозрастов
{
Т Джонзнак равно одиннадцать;
Ты Питерзнак равно 12,3;
Т Мэризнак равно 13;
U Joyзнак равно 14,6;
};

U и T видны внутри блока.

Для прототипа шаблонной функции область действия начинается от точки объявления до конца списка параметров функции, как в следующем заявлении:

шаблон<typenameТ,typenameU> пустотафункция(Ты нет, ты, ча,const char *п);

Однако, когда дело доходит до описания (определения) класса, область видимости также может состоять из разных частей, как в следующем коде:

#включают
с использованием пространство именчасы;

шаблон<классТ,классU> классTheCla
{
общественный:
t число;
статическийU ch;

пустотафункция(У отца,const char *п)
{
Стоимость << 'Есть ' <<на одной<< 'книги стоят' <<нет<<п<< ' в магазине.' << ' п';
}
статический пустотавеселье(U ch)
{
если (ch== 'к')
Стоимость << 'Официальная статическая функция-член' << ' п';
}
};

intглавный()
{
TheCla<int,char>объект;
объектна одной знак равно 12;
объектфункция('$','500');

возвращение 0;
}

Имя Скрытие

Пример сокрытия имени происходит, когда имя объекта того же типа повторно объявляется во вложенном блоке. Следующая программа иллюстрирует это:

#включают
с использованием пространство именчасы;

пустотаfn()
{
intкудазнак равно 3;
если (1==1)
{
intкудазнак равно 4;
Стоимость<<куда<<' п';
}
Стоимость<<куда<<' п';
}

intглавный()
{
fn();
возвращение 0;
}

Результат:
4
3

Это потому, что var во вложенном блоке скрывает var во внешнем блоке.

Возможность повторения декларации в том же объеме

Смысл объявления в том, что имя вводится (впервые) в его область видимости.

Прототип функции
Разные сущности, даже разных типов, обычно не могут быть объявлены в одной и той же области. Однако прототип функции может быть объявлен более одного раза в одной и той же области. Следующая программа с двумя прототипами функций и соответствующим определением функции иллюстрирует это:

#включают
с использованием пространство именчасы;

пустотаfn(intна одной);
пустотаfn(intна одной);

пустотаfn(intна одной)
{
Стоимость<<на одной<<' п';
}

intглавный()
{
fn(5);

возвращение 0;
}

Программа работает.

Перегруженные функции
Перегруженные функции - это функции с одинаковыми именами, но разными сигнатурами. В качестве другого исключения перегруженные функции с тем же именем могут быть определены в той же области. Следующая программа иллюстрирует это:

#включают
с использованием пространство именчасы;

пустотаfn(intна одной)
{
Стоимость<<на одной<<' п';
}

пустотаfn(плаватьнет)
{
Стоимость<<нет<<' п';
}

intглавный()
{
fn(5);
плаватьfltзнак равно 8,7;
fn(flt);

возвращение 0;
}

Результат:
5
8,7

Перегруженные функции определены в глобальной области видимости.

Область действия пространства имен

Область действия пространства имен заслуживает отдельной статьи. Указанная статья написана для этого веб-сайта linuxhint.com. Просто введите поисковые слова Namespace Scope в поле поиска этого сайта (страницы) и нажмите OK, и вы получите статью.

Объем в разных частях

Класс - не единственная схема, в которой область видимости может быть в разных частях. Спецификатор друга, определенные варианты использования спецификатора детализированного типа и директивы using - это другие схемы, в которых область видимости находится в разных местах - подробности см. Ниже.

Заключение

Область видимости - это декларативная область. Декларативная область - это самая большая часть текста программы, в которой допустимо имя объекта. Его можно разделить более чем на одну часть в соответствии с определенными схемами программирования, такими как вложенные блоки. Части, не имеющие точки объявления, образуют потенциальную область видимости. Потенциальный объем может иметь или не иметь декларацию.