Pane::x = x;
Pane::y = у;
Ключевое слово using
Ключевое слово using может использоваться и как оператор, и в качестве спецификатора при объявлении членов пространства имен, но синтаксис использования using при этом меняется.
Использование using как оператора
С помощью ключевого слова using расширяются области видимости всех членов пространства имен. Впоследствии это позволяет ссылаться на члены пространства имен, не указывая соответствующее имя пространства. Использование using показано в следующем примере:
namespace Window {
int valuo1 = 20;
int value2 - 40;
}
...
Window::value1 = 10;
using namespace Window;
value2 = 30;
Все члены пространства имен Window становятся видимыми, начиная от строки using namespace Window; и до конца соответствующего модуля программы. Обратите внимание, что если для обращения к переменной value1 в верхней части фрагмента программы необходимо указывать пространство имен, то в этом нет необходимости при обращении к переменной value2, поскольку оператор using сделал видимыми все члены пространства имен Window.
Оператор using может использовать в любом модуле программы с различной областью видимости. Когда выполнение программы выходит за область видимости данного модуля, автоматически становятся невидимыми все члены пространства имен, открытые в этом модуле. Проанализируйте это на следующем примере:
namespace Window {
int value1 = 20;
int value2 = 40 ;
}
//...
void f()
{
{
using namespace Window ; value2 = 30 ;
}
value2 = 20 ; //ошибка!
}
Последняя строка кода функции f() — value2 = 20 — вызовет ошибку во время компиляции, поскольку переменная value2 в этом месте невидима. Видимость этой переменной, заданная оператором using, закончилась сразу за закрывающими фигурными скобками в предыдущей строке программы.
В случае объявления внутри модуля локальных переменных все одноименные переменные пространства имен, открытые в этом модуле, будут скрыты. Это аналогично сокрытию глобальных переменных локальными в случае совпадения их областей видимости. Даже если переменная, объявленная в пространстве имен, будет открыта с помощью using после объявления локальной переменной, последняя все равно будет иметь приоритет. Это наглядно показано в следующем примере:
namespace Window {
int value1 = 20;
int value2 = 40 ;
}
//...
void f()
{
int value2 = 10;
using namespace Window;
std::cout << value2 << std::endl;
}
При выполнения этой функции на экране появится значение 10, а не 40, подтверждая тот факт, что переменная value2 пространства имен Window скрывается переменной value2 функции f(). Если все же требуется использовать переменную пространства имен, явно укажите имя пространства.
При использовании одноименных идентификаторов, один из которых объявлен как глобальный, а другой — внутри пространства имен, также может возникнуть двусмысленность. Чтобы избежать ее, всегда явно указывайте имя пространства при вызове объекта, как в следующем фрагменте программы:
namespace Window {
int value1 = 20;
}
//...
using namespace Window;
int value1 = 10;
void f()
{
value1 = 10 ;
}
В данном примере неопределенность возникает внутри функции f(). Оператор using сообщает переменной Window::value1 глобальную область видимости. Однако в программе объявляется другая глобальная переменная с таким же именем. Какая из них используется в функции f()? Обратите внимание, что ошибка будет показана не во время объявления одноименной глобальной переменной, а при обращении к ней в теле функции f().
Использование using в объявлениях
Назначение using в объявлениях идентификаторов аналогично использованию using как оператора с той лишь разницей, что обеспечивается более высокий уровень контроля. Этот способ используется для открытия видимости только для одного идентификатора, объявленного в пространстве имен, как показано в следующем примере:
namespace Window {
int value1 = 20;
int value2 = 40;
int value3 = 60;
}
//...
using Window::value2; //открытие доступа к value2 в текущем модуле
Window::value1 = 10; //для value1 необходимо указание пространства имен
value2 = 30;
Window::value3 = 10; // для value3 необходимо указание пространства имен
Итак, с помощью using можно открыть доступ в текущую область видимости к отдельному идентификатору пространства имен, не повлияв на остальные идентификаторы, заданные в этом пространстве. В предыдущем примере переменная value2 вызывается без явного указания пространства имен, что невозможно при обращении к value1 и value3. Использование using при объявлении обеспечивает дополнительный контроль над видимостью каждого идентификатора пространства имен. В этом и заключается отличие от использования using как оператора, открывающего доступ сразу ко всем идентификаторам пространства имен.
Видимость имени распространяется до конца блока, что можно сказать и о любом другом объявлении. С помощью using идентификаторы можно объявлять как глобально, так и в локальной области.
Если в локальную область, где уже объявлен идентификатор из пространства имен, добавляется другой идентификатор с таким же именем, это приводит к ошибке компиляции. Ошибкой будет и объявление идентификатора из пространства имен в области, где уже существует другой идентификатор с таким же именем. Это показано в следующем примере:
namespace Window {
int value1 = 20;
int value2 = 40;
}
//...
void f()
{
int value2 = 10;
using Window::value2; // ряд обьявлеиий
std::cout << value2 << std::endl;
}
Компиляция второй строки функции f() приведет к ошибке, поскольку переменная с именем value2 в этом блоке уже объявлена. Тот же результат получится, если объявление с using разместить перед объявлением локальной переменной valuo2.
Идентификатор пространства имен, введенный в локальную область с помошью using, скрывает аналогичный идентификатор, объявленный за пределами этой области. Проанализируйте следующий пример:
namespace Window {
int value1 - 20;
int va]ue2 - 40;
}
int value2 = 10;
//...
void f()
{
using Window::value2;
std::cout << value2 << std::endl;
}
Объявление переменной с помощью using в функции f() скрывает глобальную переменную value2.
Как отмечалось ранее, этот способ использования using позволяет дополнительно контролировать области видимости отдельных идентификаторов пространства имен. Оператор using открываетдоступ n локальной области ко всем идентификаторам, объявленным в пространстве имен. Поэтому предпочтительней использовать using в объявлениях, а не как оператор, чтобы п полной мере воспользоваться всеми преимуществами, предоставляемыми пространством имени. Явное расширение области видимости для отдельных идентификаторов позволяет снизить вероятность возникновения конфликтов имен. Использование оператора using оправдано только в том случае, если необходимо открыть доступ сразу ко всем идентификаторам пространства имен.
Псевдонимы пространства имен
Псевдонимы пространства имен используется для создания дополнительного имени именованного пространства. Как правило, псевдоним представляет собой информативный термин, используемый для ссылки на пространство имен. Это весьма эффективно, если имя пространства очень длинное. Создание псевдонимов поможет упростить дальнейшую работу с пространствами имен. Рассмотрим следующий пример:
namespace the_software_company {
int value;
//...
}
the_software_company::value = 10;
...
namespace TSC = the_software_company;
TSC::value = 20;
Недостаток этого метода состоит в том, что подобный псевдоним может уже существовать в указанной области видимости. В этом случае компилятор сообщит об ошибке, и вы сможете просто изменить псевдоним.
Неименованные пространства имен
Такие пространства имен отличаются от именованных тем, что не имеют имени. Наиболее часто они используются для защиты глобальных данных от потенциальных конфликтов имен. Каждая единица программы имеет собственное уникальное неименованное пространство. Все идентификаторы, объявленные внутри такого пространства имен, вызываются просто по имени без каких-либо префиксов. В следующем коде представлены примеры двух неименованных пространств, расположенных в двух разных файлах.
// файл: one.cpp
namespace {
int value;
char p(char *p);
//...
}
// файл: two.cpp
namespace {
int value;
char p(char *p);
//...
}
int main()
{