Відповіді:
Ви в основному посилаєтесь на розділ § 7.3.1.1 / 2 стандарту C ++ 03,
Використання статичного ключового слова припиняється при оголошенні об'єктів в області простору імен; простір імен без імен пропонує чудову альтернативу.
Зауважте, що цей абзац уже видалено в C ++ 11. 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
.
Також зауважте, що використання статичного ключового слова застаріло при оголошенні об'єктів в області простору імен (відповідно до стандарту).
deprecated
зауваження було видалено з останнього C ++ 0x FCD (n3225).
.cpp
визначає клас з тим самим іменем.
З цим пов'язана цікава проблема:
Припустимо, ви використовуєте static
ключове слово або без імені, namespace
щоб зробити якусь функцію внутрішньої для модуля (блоку перекладу), оскільки ця функція призначена для використання модулем внутрішньо і не доступна поза ним. (Безіменні namespace
s мають перевагу в тому, що вони роблять внутрішні визначення даних і типів, крім функцій).
З часом вихідний файл реалізації вашого модуля зростає, і ви хочете розділити його на кілька окремих вихідних файлів, що дозволило б краще організувати код, швидше знаходити визначення та збиратись самостійно.
Але тепер у вас виникає проблема: ці функції вже не можуть бути static
модулями, оскільки static
насправді вони не відносяться до модуля , а до вихідного файла (блоку перекладу). Ви змушені робити їх не-, static
щоб дозволити їм доступ з інших частин (файлів об'єктів) цього модуля. Але це також означає, що вони більше не приховані / приватні для модуля: маючи зовнішній зв'язок, до них можна отримати доступ з інших модулів, що не було вашим початковим наміром.
Безіменна namespace
також не вирішить цю проблему, тому що вона також визначена для певного вихідного файлу (перекладацького блоку) і не може бути доступна ззовні.
Було б чудово, якби можна було вказати, що деяке namespace
є private
, тобто те, що в ньому визначено, призначене для внутрішнього використання модулем, якому він належить. Але звичайно C ++ не має такого поняття, як "модулі", лише "одиниці перекладу", які тісно пов'язані з вихідними файлами.
Стандарт C ++ зазначається в розділі 7.3.1.1. Безназовні простори імен, параграф 2:
Використання статичного ключового слова припинено при оголошенні об'єктів в області простору імен, простір безіменних імен надає чудову альтернативу.
Статичний характер стосується лише імен об'єктів, функцій та анонімних об'єднань, а не для введення декларацій.
static
.