Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Using namespace CounterNameSpace; // Все члены видимы.



upperbound = 100; // Все в порядке, поскольку все члены видимы.

Использование инструкции using демонстрируется в следующей программе (которая представляет собой новый вариант счетчика из предыдущего раздела).

// Использование инструкции using.

#include < iostream>

using namespace std;

namespace CounterNameSpace {

  int upperbound;

  int lowerbound;

  class counter {

      int count;

    public:

      counter (int n) {

        if(n < = upperbound) count = n;

        else count = upperbound;

      }

      void reset(int n) {

        if(n < = upperbound) count = n;

      }

      int run() {

        if(count > lowerbound) return count--;

        else return lowerbound;

      }

  };

}

Int main()

{

  /* Используется только член upperbound из пространства имен CounterNameSpace. */

  using CounterNameSpace:: upperbound;

  /* Теперь для установки значения переменной upperbound не нужно указывать пространство имен. */

  upperbound = 100;

  /* Но при обращении к переменной lowerbound и другим объектам по-прежнему необходимо указывать пространство имен. */

  CounterNameSpace:: lowerbound = 0;

  CounterNameSpace:: counter ob1(10);

  int i;

  do {

    i = ob1.run();

    cout < < i < < " ";

  }while(i > CounterNameSpace:: lowerbound);

  cout. < < endl;

  /* Теперь используем все пространство имен CounterNameSpace. */

  using namespace CounterNameSpace;

  counter ob2(20);

  do {

    i = ob2.run();

    cout < < i < < " ";

  }while(i > lowerbound);

  cout < < endl;

  ob2.reset(100);

  lowerbound = 90;

  do {

    i = ob2.run();

    cout < < i < < " ";

  }while(i > lowerbound);

  return 0;

}

Эта программа иллюстрирует еще один важный момент. Использование одного пространства имен не переопределяет другое. Если некоторое пространство имен становится " видимым" , это значит, что оно просто добавляет свои имена к именам других, уже действующих пространств. Поэтому к концу этой программы к глобальному пространству имен добавились и std, и CounterNameSpace.

Неименованные пространства имен

Неименованное пространство имен ограничивает идентификаторы рамками файла, в котором они объявлены.

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

namespace {

  // объявления

}

Неименованные пространства имен позволяют устанавливать уникальные идентификаторы, которые известны только в области видимости одного файла. Другими словами, члены файла, который содержит неименованное пространство имен, можно использовать напрямую, без уточняющего префикса. Но вне файла эти идентификаторы неизвестны.

Как упоминалось выше в этой книге, использование модификатора типа static также позволяет ограничить область видимости глобального пространства имен файлом, в котором он объявлен. Например, рассмотрим следующие два файла, которые являются частью одной и той же программы.

Поскольку переменная k определена в файле One, ее и можно использовать в файле One. В файле Two переменная k определена как внешняя (extern-переменная), а это значит, что ее имя и тип известны, но сама переменная k в действительности не определена. Когда эти два файла будут скомпонованы, попытка использовать переменную k в файле Two приведет к возникновению ошибки, поскольку в нем нет определения для переменной k. Тот факт, что k объявлена static-переменной в файле One, означает, что ее область видимости ограничивается этим файлом, и поэтому она недоступна для файла Two.

Несмотря на то что использование глобальных static-объявлений все еще разрешено в C++, для локализации идентификатора в рамках одного файла лучше использовать неименованное пространство имен. Рассмотрим пример.

Здесь переменная k также ограничена рамками файла One. Для новых программ рекомендуется использовать вместо модификатора static неименованное пространство имен.

Обычно для большинства коротких программ и программ среднего размера нет необходимости в создании пространств имен. Но, формируя библиотеки многократно используемых функций или классов, имеет смысл заключить свой код (если хотите обеспечить его максимальную переносимость) в собственное пространство имен.

Пространство имен std

Пространство имен std используется библиотекой C++.

Стандарт C++ определяет всю свою библиотеку в собственном пространстве имен, именуемом std. Именно по этой причине большинство программ в этой книге включает следующую инструкцию:

using namespace std;

При выполнении этой инструкции пространство имен std становится текущим, что открывает прямой доступ к именам функций и классов, определенных в этой библиотеке, т.е. при обращении к ним отпадает необходимость в использовании префикса std:: .

Конечно, при желании можно явным образом квалифицировать каждое библиотечное имя префиксом std:: . Например, следующая программа не привносит библиотеку в глобальное пространство имен.

// Использование явно заданной квалификации std::.

#include < iostream>

Int main()

{

  double val;

  std:: cout < < " Введите число: ";

    std:: cin > > val;

  std:: cout < < " Вы ввели число ";

  std:: cout < < val;

  return 0;

}

Здесь имена cout и cin явно дополнены именами своих пространств имен. Итак, чтобы записать данные в стандартный выходной поток, следует использовать не просто имя потока cout, а имя с префиксом std:: cout, а чтобы считать данные из стандартного входного потока, нужно применить " префиксное" имя std:: cin.

Если ваша программа использует стандартную библиотеку только в ограниченных пределах, то, возможно, ее и не стоит вносить в глобальное пространство имен. Но если ваша программа содержит сотни ссылок на библиотечные имена, то гораздо проще сделать пространство имен std текущим, чем полностью квалифицировать каждое имя в отдельности.

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

/* Внесение в глобальное пространство имен лишь нескольких имен.

*/

#include < iostream>

// Получаем доступ к именам потоков cout и cin.

using std:: cout;

using std:: cin;

Int main()

{

  double val;

  cout < < " Введите число: ";

    cin > > val;

  cout < < " Вы ввели число ";

  cout < < val;

  return 0;

}

Здесь имена потоков cin и cout можно использовать напрямую, но остальная часть пространства имен std не внесена в область видимости.

Как упоминалось выше, исходная библиотека C++ была определена в глобальном пространстве имен. Если вам придется модернизировать старые С++-программы, то вы должны либо включить в них инструкцию using namespace std, либо дополнить каждое обращение к члену библиотеки префиксом std:: . Это особенно важно, если вам придется заменять старые заголовочные *.h-файлы современными заголовками. Помните, что старые заголовочные *.h-файлы помещают свое содержимое в глобальное пространство имен, а современные заголовки — в пространство имен std.

Указатели на функции

Указатель на функцию ссылается на входную точку этой функции.

Указатель на функцию— это довольное сложное, но очень мощное средство C++. Несмотря на то что функция не является переменной, она, тем не менее, занимает физическую область памяти, некоторый адрес которой можно присвоить указателю. Адрес, присваиваемый указателю, является входной точкой функции. (Именно этот адрес используется при вызове функции.) Если некоторый указатель ссылается на функцию, то ее (функцию) можно вызвать с помощью этого указателя.

Указатели на функции также позволяют передавать функции в качестве аргументов другим функциям. Адрес функции можно получить, используя имя функции без круглых скобок и аргументов. (Этот процесс подобен получению адреса массива, когда также используется только его имя без индекса.) Если присвоить адрес функции указателю, то эту функцию можно вызвать через указатель. Например, рассмотрим следующую программу. Она содержит две функции, vline() и hline(), которые рисуют на экране вертикальные и горизонтальные линии заданной длины.

#include < iostream>

using namespace std;

void vline(int i), hline(int i);

Int main()

{

  void (*p)(int i);

  p = vline; // указатель на функцию vline()

  (*p)(4); // вызов функции vline()

  p = hline; // указатель на функцию hline()

  (*p)(3); // вызов функции hline()

  return 0;

}

Void hline(int i)

{

  for(; i; i--) cout < < " -";

  cout < < " ";

}

Void vline(int i)

{

  for(; i; i--) cout < < " |";

}


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-03-17; Просмотров: 1569; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.024 с.)
Главная | Случайная страница | Обратная связь