Когда целесообразно использовать статические (над неназванными пространствами имен) в C ++? - PullRequest
7 голосов
/ 08 октября 2010

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

#ifndef HEADER_H
#define HEADER_H

static int func() {
  ...
}

// versus:

namespace {
  int func() {
    ...
  }
};

#endif // HEADER_H 

Или как насчет статических функций-членов?

Привет

Ответы [ 4 ]

5 голосов
/ 08 октября 2010

Точная формулировка стандарта:

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

Функции в заголовкефайл должен быть inline, а не static или в безымянном пространстве имен.inline означает, что вы получите не более одной копии функции в вашей программе, в то время как другие методы предоставят вам отдельную копию из каждого файла, содержащего заголовок.Помимо раздувания, это может привести к некорректному поведению, если функция содержит статические данные функции.( EDIT: , за исключением случаев, когда предполагается, что функция имеет разные определения в разных блоках компиляции, возможно, из-за разных макросов препроцессора, которые были определены до включения файла заголовка. В этом случае лучший подход не включать еговсе, но вместо этого похоронить его в безымянной могиле с колом в его нечестивом сердце.)

Объекты данных, кроме констант, обычно вообще не должны определяться в заголовочных файлах, только объявлены extern.

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

ОБНОВЛЕНИЕ: C ++ 11 удалило устаревание, поэтому больше нет особой причины предпочитать безымянные пространства именсвыше staticНо вам все равно не следует использовать ни один из заголовочных файлов, если вы не делаете что-то странное.

3 голосов
/ 08 октября 2010

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

В отдельно скомпилированном файле реализации вы можете использовать static или анонимное пространство имен, чтобы избежать коллизий имен на уровне связи.или клиентский код, основанный на деталях реализации.Анонимное пространство имен позволяет вам иметь внешнюю связь, которая требуется для параметров шаблона, а также поддерживает определения классов.Но, в конце концов, это просто вопрос практичности и личных предпочтений, в каждом конкретном случае.

static для функции-члена не имеет ничего общего со спецификацией связи.Функция члена static в любом случае имеет внешнюю связь.

3 голосов
/ 08 октября 2010

Нет статического преимущества в пространстве имен по сравнению с безымянными пространствами имен, о которых я знаю.Используйте безымянные пространства имен, как в примере выше.На самом деле в приведенном выше примере я не вижу, почему необходимо статическое или безымянное пространство имен.Может быть, встроенный?И статические функции-члены не имеют ничего общего со статической областью имен.Статические функции-члены (и не-функции) по-прежнему действительны.

0 голосов
/ 09 октября 2010

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

Пример вопроса, который дает некоторую подсказку о потенциальной боли в отделе отладки:

Просмотр глобальных переменных пространства имен в отладчике Visual Studio?

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

МойЛичная рекомендация заключается в том, что для кода, который будет существовать менее чем навсегда, можно было бы также пойти с static.Эффективно действует так же, как и безымянное пространство имен, но, усредненное по всем инструментам, оно лучше поддерживается.Теоретически, однажды он полностью исчезнет, ​​но я рад публично признать, что уверен, что этот день никогда не наступит.А пока вы избавляете себя от боли.

...