Превосходство безымянного пространства имен над статическим?
Как безымянные пространства имен превосходят static
ключевое слово?
3 ответа
Вы в основном ссылаетесь на раздел $7.3.1.1/2 из стандарта C++,
Использование статического ключевого слова не рекомендуется при объявлении объектов в области пространства имен; Пространство имен без имен обеспечивает превосходную альтернативу.
Безымянное пространство имен превосходит статическое ключевое слово, прежде всего потому, что ключевое слово 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
ключевое слово или без имени namespace
сделать некоторую функцию внутренней для модуля (модуля перевода), поскольку эта функция предназначена для внутреннего использования модулем и недоступна за ее пределами. (Без имени namespace
Кроме того, у них есть преимущество, заключающееся в том, что они делают внутренние определения данных и типов, помимо функций).
Со временем исходный файл реализации вашего модуля становится больше, и вы хотели бы разделить его на несколько отдельных исходных файлов, которые позволили бы лучше организовать код, быстрее находить определения и компилироваться независимо.
Но теперь вы столкнулись с проблемой: эти функции больше не могут быть static
к модулю, потому что static
на самом деле относится не к модулю, а к исходному файлу (блоку перевода). Вы вынуждены сделать их неstatic
разрешить доступ к ним из других частей (объектных файлов) этого модуля. Но это также означает, что они больше не являются скрытыми / закрытыми для модуля: имея внешнюю связь, они могут быть доступны из других модулей, что не было вашим первоначальным намерением.
неназванный namespace
также не решит эту проблему, потому что он также определен для определенного исходного файла (единицы перевода) и недоступен извне.
Было бы здорово, если бы можно было namespace
является private
то есть все, что в нем определено, предназначено для внутреннего использования тем модулем, к которому он принадлежит. Но, конечно, C++ не имеет такого понятия, как "модули", только "единицы перевода", которые тесно связаны с исходными файлами.
Стандарт C++ гласит в разделе 7.3.1.1 Безымянные пространства имен, параграф 2:
Использование статического ключевого слова не рекомендуется при объявлении объектов в области пространства имен. Пространство без имени обеспечивает превосходную альтернативу.
Статика применяется только к именам объектов, функций и анонимных объединений, но не к объявлениям типов.