Вы уже познакомились с первой статьей по теме Локальные и глобальные переменные. Область видимости в С++. Хотелось бы ещё немного дополнить её. А именно примером с пространствами имен. Я не зря писал префикс std:: перед оператором вывода cout. и endl. Это тоже одна из формаций области видимости – пространство имен. Если не вдаваться в особые подробности, пространство имен, это некая группа операторов / функций / переменных / типов, объединенная в такую себе “фракцию” с именем std.
std это пространство имен из заголовочного файла (хедера по нашему) iostream. cout, cin, endl и др. – это все “династия” std. Если не подключить его в коде и не написать std:: перед этими операторами, С++ скажет “давай до свиданья”. Потому что он не в курсе, что это за cout такой без “фамилии”. Кстати в С++ и придуман оператор using namespace, который позволяет не писать имя пространства в качестве префикса к каждому входящему в него оператору . Это для удобства сделано, но нужно с этим оператором быть аккуратнее, если есть одноименные функции используемые в программе из разных пространств имен.
Пространство имен хорошо там, где нужно сгруппировать что-то в область видимости по имени. Например в программе могут быть описаны две разные функции sum(). Одна возвращает целое, вторая вещественное. Если по заданию их нельзя описывать как перегруженные, то можно вкрутить их в пространство имен:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <iostream> int i = 2; namespace integer { int sum() { int k = 2; return i + k; } } namespace floating { float sum() { float k = 2.5; return k + i; } } int main() { std::cout << integer::sum() << std::endl; std::cout << floating::sum() << std::endl; } |
Пространство имен тут определяет область видимости для разных функций с одинаковым именем. За пределами пространства имен этих функций не существует.
Вообще пространство имен может стать спорным моментом относительно теории области видимости. По факту это просто группировка по имени, но действует она так же, как и блок операторов {…}. Хочешь обратиться к операторам из этого пространства – будь добр обратись сначала к имени пространства: integer :: sum() Тут двоеточие :: – это оператор расширения области видимости.
Пожалуй последнее, что можно сказать – область видимости весьма показательна в ООП (объектно ориентированное программирование). Когда в классе программист описывает private свойство (переменую или функцию-метод), он задает ей область видимости. Например в коде типа:
1 2 3 4 5 6 7 8 9 10 | class C { private: int k; public: int kc; int sum() { return k + kc; } }; |
Свойства k и kc имеют разные области видимости. Первая доступна только внутри методов класса. К ней нельзя обратиться в основной программе, она приватная (private ). Закрытая для всех, кроме области видимости самого класса.
Вторая публичная (public). Её область видимости выходит за пределы класса. Из программы, где будет вызываться объект этого класса она доступна.
kc объявлена как публичная переменная, её область видимости в отличии от переменой k , шире. Поэтому компилятор не против её использования вне пределов класса.
Какой можно сделать из всего этого вывод? Гики с пеной у рта кричат на всех порталах – “долой глобальные переменные!”. Гикам нравится ограничивать область видимость, локализуя и упаковывая всё в классы или пространства имен. Гики есть гики. Программист не должен злоупотреблять областью видимости, иначе получится, оказия, когда чтоб обратиться к переменной нужно писать её путь. Т.е. что-то типа myname::group1::PeremenkiDlaPrepoda::i Ну жесть просто.
Использование глобальных переменных наряду с локальными должно быть с умом – там где это целесообразно писать глобальную. Там где нет – локализовать.
Если вы не смотрели видео по теме Область видимости в С++ в предыдущем уроке – размещаем его и тут:
r5av7s