статическое ключевое слово бесполезно в области имен? - PullRequest
20 голосов
/ 17 мая 2011
namespace N
{
   static int x = 5;
}

Каковы могут быть важность / случаи использования объявления статической переменной в области именного пространства?

Ответы [ 6 ]

29 голосов
/ 17 мая 2011

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

11 голосов
/ 17 мая 2011

Приложение D (Совместимость) [C ++ 03]

D2. Использование статического ключевого слова не рекомендуется при объявлении объектов в области имен.

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

Статическое ключевое слово придает внутреннюю связь переменным / объектам в C, а также в C ++ в области имен, как другие упоминали в своих постах.

P.S: Эта функция была устаревшей согласно последней версии (n3290). В n3225 §7.3.1.1/2 присутствует, но вычеркнут.

1 голос
/ 17 мая 2011

То, что уже говорили другие, с дополнительной тонкостью: static вводит внутреннюю связь, а анонимные пространства имен - нет.

1 голос
/ 17 мая 2011

C ++ Standard & sect; 7.3.1.1/2:

Использование статического ключевого слова не рекомендуется при объявлении объектов в область действия пространства имен (см. приложение D); безымянное пространство имен обеспечивает превосходное Альтернатива.

Если безымянное пространство имен не обеспечивает превосходную альтернативу в будущем стандарте , для достижения совместимости с Си будет недопустимым .

0 голосов
/ 26 апреля 2018

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

Например: header.h

namespace test{
    static int i = 5;//definition is here.And there will be no multiple definition!
    void set_i();
    void print_i();
}

header.cpp

#include "header.h"
#include "iostream"
void test::set_i()
{
    i = 10;
    return;
}

void test:print_i()
{
    using namespace std;
    cout << "print_i is " << i << endl;
    return;
}

main.cpp

#include "header.h"
#include "iostream"
using std::cout;
int main()
{
    test::i = 20;
    test::set_i();
    cout << "i is " << test::i << endl; 
    test::print_i();
    return 0;
}

Используйте g++ -std=c++11 header.cpp main.cpp для его компиляции, и вы не получите multiple definition error. Если вы удалите ключевое слово static и скомпилируете, это определенно будет multiple definition error. И, пожалуйста, запустите программу и наблюдайте за результатом, и вы можете быть удивлены.

static ключевое слово делает каждый файл реализации cpp (модуль перевода), который включает в себя заголовок интерфейса, который содержит объявление пространства имен, имеет копию статической переменной с внутренней связью. Таким образом, даже если вы определите эту переменную в пространстве имен, если она имеет static keyworded, ошибки множественного определения не будет (то же самое для const без extern перед ним, которые определяют переменную внутренней связи, и это как макросы может быть отброшено в C ++) Поэтому высказывание о том, что переменные, определенные в пространстве имен, неявно являются статическими, неверно, а статические не являются полностью бесполезными в пространстве имен. Поскольку каждая единица перевода имеет одну копию этой переменной, пространство используется.

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

0 голосов
/ 17 мая 2011

То же, что и объявление статического в глобальном пространстве имен, но только локальное для определенного пространства имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...