Ответы:
Вы в основном имеете в виду раздел §7.3.1.1 / 2 стандарта C ++ 03,
Использование ключевого слова static не рекомендуется при объявлении объектов в области пространства имен; безымянное пространство имен обеспечивает превосходную альтернативу.
Обратите внимание, что этот абзац уже был удален в C ++ 11. стандартные функции больше не static
считаются устаревшими!
Тем не менее, пространства имен без названия превосходят ключевое слово static, прежде всего потому, что это ключевое слово static
применяется только к объявлениям переменных и функциям, а не к определяемым пользователем типам .
Следующий код действителен в C ++
//legal code
static int sample_function() { /* function body */ }
static int sample_variable;
Но этот код НЕ действителен:
//illegal code
static class sample_class { /* class body */ };
static struct sample_struct { /* struct body */ };
Итак, решение - безымянное пространство имен, то есть
//legal code
namespace
{
class sample_class { /* class body */ };
struct sample_struct { /* struct body */ };
}
Надеюсь, это объясняет, почему unnamed-namespace
лучше static
.
Также обратите внимание, что использование ключевого слова static устарело при объявлении объектов в области пространства имен (согласно Стандарту).
deprecated
замечание было удалено из последней версии C ++ 0x FCD (n3225).
.cpp
связаны с определением класса с тем же именем.
С этим связана интересная проблема:
Предположим, вы используете static
ключевое слово или безымянный, namespace
чтобы сделать некоторую функцию внутренней по отношению к модулю (единицей перевода), поскольку эта функция предназначена для внутреннего использования модулем и недоступна вне его. (Безымянный namespace
s имеет то преимущество, что делает данные и определения типов также внутренними, помимо функций).
Со временем исходный файл реализации вашего модуля становится большим, и вы хотели бы разделить его на несколько отдельных исходных файлов, что позволило бы лучше организовать код, быстрее находить определения и компилировать независимо.
Но теперь вы сталкиваетесь с проблемой: эти функции больше не могут относиться static
к модулю, потому static
что на самом деле они относятся не к модулю , а к исходному файлу (единице перевода). Вы вынуждены сделать их запрещенными, static
чтобы разрешить к ним доступ из других частей (объектных файлов) этого модуля. Но это также означает, что они больше не скрыты / закрыты для модуля: имея внешнюю связь, к ним можно получить доступ из других модулей, что не было вашим первоначальным намерением.
Без имени namespace
также не решит эту проблему, потому что он также определен для определенного исходного файла (единицы перевода) и не может быть доступен извне.
Было бы замечательно, если бы можно было указать, что some namespace
is private
, то есть все, что в нем определено, предназначено для внутреннего использования модулем, которому он принадлежит. Но, конечно, в C ++ нет понятия «модули», только «единицы перевода», которые жестко привязаны к исходным файлам.
static
работают и работают.