Глобальная область и глобальное пространство имен


Я видел использование этих двух фраз: global scope и global namespace. В чем разница между ними?

5   51   2012-04-22 18:58:31

5 ответов:

в C++ каждое имя имеет свою область, вне которой оно не существует. Область действия может быть определена многими способами: она может быть определена с помощью пространство имен,функции,классы и просто { }.

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

int a; //this a is defined in global namespace
       //which means, its scope is global. It exists everywhere.

namespace N
{
     int a;  //it is defined in a non-global namespace called `N`
             //outside N it doesn't exist.
}
void f()
{
   int a;  //its scope is the function itself.
           //outside the function, a doesn't exist.
   {
        int a; //the curly braces defines this a's scope!
   }
}
class A
{
   int a;  //its scope is the class itself.
           //outside A, it doesn't exist.
};

также обратите внимание, что a имя может быть скрыт внутренней областью, определяемой пространством имен, функцией или классом. Так что имя a внутри пространства имен N скрывает имя a в глобальном пространстве имен. Точно так же имя в функции и классе скрывает имя в глобальном пространстве имен. Если вы столкнулись с такой ситуацией, то вы можете используйте ::a для ссылки на имя, определенное в глобальном пространстве имен:

int a = 10;

namespace N
{
    int a = 100;

    void f()
    {
         int a = 1000;
         std::cout << a << std::endl;      //prints 1000
         std::cout << N::a << std::endl;   //prints 100 
         std::cout << ::a << std::endl;    //prints 10
    }
}

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

"глобальная область "и" глобальное пространство имен " могут использоваться более или менее взаимозаменяемо; область имени, объявленного в пространстве имен, охватывает все это пространство имен. Используйте "пространство имен", если вы конкретно ссылаетесь на пространство имен, и "область", если вы имеете в виду видимость имен внутри него.

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

#include <iostream>

int a = 100;

main () {
    int a = 200;

    std::cout << "local a is: " << a << std::endl;
    std::cout << "global a is: " << ::a << std::endl;

    return 0;
}

при выполнении оператор будет печатать local a is: 200, что, очевидно, ожидается, потому что мы переопределяем a на main который выходит в объем его заключая блока. Мы также печатаем глобальный ::a который снова выводит ожидаемое значение 100, потому что мы запросили глобальное пространство имен ::.

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

Scope с другой стороны, обозначает срок службы объекта, глобальный a возник перед местным a потому что он строится гораздо раньше, чем main получает выполненный. Однако, область также сил пространство имен на символе, но не так, как A namespace делает. Существуют различные виды областей,global,class,function,block,file etc...

запутанная часть заключается в том, что область иногда перегружается для обозначения видимости конкретного символа, который является чем-то заимствованным из C, где понятие пространств имен не существовало, а область использовалась для обозначения как продолжительности жизни, так и видимости. В C++, однако правила немного изменились, но термин scope по-прежнему используется таким же образом, потому что два языка имеют много общих понятий.

при объявлении глобальной переменной int i например, мы говорим:i is in the global namespace и has the global namespace scope. Вот и все.

Отрывок Из C++03:

3.3.5 Namespace scope   

    The outermost declarative region of a translation unit is also a namespace, called
  the global namespace. A name declared in the global namespace has global namespace
  scope (also called global scope).

@Dmitriy Ryajov

тема немного старая, но я хочу предложить свою помощь по этому поводу. Я думаю, что вы не должны делать вещи более сложными, чем они есть на самом деле. Scope идентификатора является частью компьютерной программы, где идентификатор, имя, которое ссылается на некоторую сущность в программе, может быть использован для поиска упомянутой сущности. Поэтому срок применения относится только к идентификаторам и мы не должны смешивать его с временем жизни объекта. Они несколько связаны но не стоит путаться. Время жизни объекта обозначается, где мы выделяем память для этого объекта. Так, например, если память выделена в стеке, она будет освобождена, как только функция завершится. Так это зависит от того, где мы храним объект и что обозначает его жизни. Объем только говорит: "Вот это имя для объекта, и мы можем использовать это имя для объекта до и после". Итак, как я уже сказал, термин scope только для идентификаторов объектов и жизни это что-то еще, что обозначается тем, где мы храним объект.

кроме того, я хочу сказать кое-что о linkage что тесно связано с этим. Это также может иногда сбивать с толку. Допустим, у нас есть некоторые идентификаторы в translation unit которые относятся к некоторым объектам. То ли те же идентификаторы в other единица перевода будет ссылаться на те же объекты, обозначенные связью. Так, например, если идентификатор имеет внешнюю связь, мы можем ссылаться на сущность, что это идентификатор относится к но из другой единицы перевода, объявив его с ключевым словом extern. Теперь, допустим, мы не хотим использовать эту сущность в других единицах. Тогда сущность будет exist пока программа не завершится, но когда мы не объявим ее, мы не сможем ссылаться на нее. Также отметим, что теперь я перепутал термины, взаимосвязь и продолжительность жизни. Но это потому, что только global субъекты внешних связей. Идентификатор внутри функции не может быть отнесен к другим частям функции. программа.

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