Я согласен с ответом Наваза: статическое ключевое слово не является абсолютно бесполезным в пространствах имен: оно определяет, что переменная имеет внутреннюю связь с единицей перевода.
Например:
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
не может «приписать» класс, так что это одно из преимуществ безымянного пространства имен. Кроме того, вы можете использовать безымянное пространство имен во вложенном пространстве имен для ограничения доступа к переменным. Безымянное пространство имен предназначено для защиты локальности, а не для предоставления интерфейса.