Перевагу неназваного простору імен над статичним?


129

Яким чином неіменовані простори імен перевершують staticключове слово?


Однак, неназвані простори імен не є достатньою заміною для простору імен-статичних , на думку комітету зі стандартів. Є ще декілька випадків, коли простої імена без імені виходять з ладу і працюють лише static.
legends2k

Відповіді:


133

Ви в основному посилаєтесь на розділ § 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.

Також зауважте, що використання статичного ключового слова застаріло при оголошенні об'єктів в області простору імен (відповідно до стандарту).


11
Більш загально, неназваний простір імен дозволяє здійснювати зовнішні зв'язки. Саме це дає змогу оголосити клас локального перекладу одиниці. Це також дозволяє, наприклад, константа зовнішнього рядка зв’язку, використовуватись як аргумент шаблону.
Ура та хт. - Альф

10
Як зазначив Фред Нурк в іншій вашій відповіді, схоже, що це deprecatedзауваження було видалено з останнього C ++ 0x FCD (n3225).
Матьє М.

36
Ви відповідаєте на власне питання і
дякуєте

11
Яка буде різниця від просто визначення класу в cpp (немає анонімного простору імен, немає статики)?
Лучіан Григоре

6
@LuchianGrigore Пов’язання проблем у випадку 2 .cppвизначає клас з тим самим іменем.
Xaqq

8

З цим пов'язана цікава проблема:

Припустимо, ви використовуєте staticключове слово або без імені, namespaceщоб зробити якусь функцію внутрішньої для модуля (блоку перекладу), оскільки ця функція призначена для використання модулем внутрішньо і не доступна поза ним. (Безіменні namespaces мають перевагу в тому, що вони роблять внутрішні визначення даних і типів, крім функцій).

З часом вихідний файл реалізації вашого модуля зростає, і ви хочете розділити його на кілька окремих вихідних файлів, що дозволило б краще організувати код, швидше знаходити визначення та збиратись самостійно.

Але тепер у вас виникає проблема: ці функції вже не можуть бути staticмодулями, оскільки staticнасправді вони не відносяться до модуля , а до вихідного файла (блоку перекладу). Ви змушені робити їх не-, staticщоб дозволити їм доступ з інших частин (файлів об'єктів) цього модуля. Але це також означає, що вони більше не приховані / приватні для модуля: маючи зовнішній зв'язок, до них можна отримати доступ з інших модулів, що не було вашим початковим наміром.

Безіменна namespaceтакож не вирішить цю проблему, тому що вона також визначена для певного вихідного файлу (перекладацького блоку) і не може бути доступна ззовні.

Було б чудово, якби можна було вказати, що деяке namespaceє private, тобто те, що в ньому визначено, призначене для внутрішнього використання модулем, якому він належить. Але звичайно C ++ не має такого поняття, як "модулі", лише "одиниці перекладу", які тісно пов'язані з вихідними файлами.


3
Це все-таки було б злому та обмеженим рішенням, але ви можете включити файли cpp з внутрішніми статичними функціями або функціями з розширенням імен у свої "головні" файли cpp. Потім виключіть ці «супутникові» файли cpp із збірки, і ви закінчите. Єдина проблема, якщо у вас є два або більше "головних" файлів cpp, і вони обидва хочуть використовувати цю класну функцію з одного з "супутникових" файлів CPP ...
Сергій

не використовує рішення успадкування з приватними / захищеними / публічними зі статичними функціями?
Алі

C ++ 20 представляє модулі, що вирішує вашу проблему.
LF

4

Стандарт C ++ зазначається в розділі 7.3.1.1. Безназовні простори імен, параграф 2:

Використання статичного ключового слова припинено при оголошенні об'єктів в області простору імен, простір безіменних імен надає чудову альтернативу.

Статичний характер стосується лише імен об'єктів, функцій та анонімних об'єднань, а не для введення декларацій.


5
Ні, це не так. Проект зробив. І ще один проект дуже скоро після цього повернув цю дурну зміну.
підкреслюй_d
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.