Adsız ad alanının statikten üstünlüğü?


Yanıtlar:


134

Temel olarak C ++ 03 Standardının §7.3.1.1 / 2 bölümüne atıfta bulunuyorsunuz,

Bir ad alanı kapsamındaki nesneler bildirilirken statik anahtar sözcüğün kullanımı kullanımdan kaldırılmıştır; isimsiz-isim-alanı daha üstün bir alternatif sağlar.

Bu paragrafın C ++ 11'de zaten kaldırıldığını unutmayın. staticişlevler standart olarak artık kullanımdan kaldırılmamaktadır!

Bununla birlikte, Adsız ad alanları static anahtar sözcüğünden daha üstündür çünkü anahtar sözcük , kullanıcı tanımlı türler için değil, staticyalnızca değişken bildirimleri ve işlevler için geçerlidir .

Aşağıdaki kod C ++ 'da geçerlidir

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variable;

Ancak bu kod geçerli DEĞİLDİR:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

Yani çözüm, adlandırılmamış ad alanıdır, bu da

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

Umarım neden unnamed-namespaceüstün olduğunu açıklar static.

Ayrıca, nesneleri bir ad alanı kapsamında bildirirken (Standart uyarınca) statik anahtar sözcüğün kullanımının kullanımdan kaldırıldığını unutmayın.


11
Daha genel olarak, adsız bir ad alanı harici bağlantıya izin verir. Yerelden çeviri birimine sınıf bildirimini etkinleştiren budur. Ayrıca, örneğin harici bağlantı dizesi sabitinin şablon argümanı olarak kullanılmasına izin verir.
Şerefe ve hth. - Alf

10
Fred Nurk'un başka bir cevabınızda belirttiği gibi, bu deprecatedaçıklama en son C ++ 0x FCD'den (n3225) kaldırılmış gibi görünüyor .
Matthieu M.

36
Kendi sorunuzu yanıtlıyorsunuz ve kendinize teşekkür ediyorsunuz: -o
manpreet singh

12
Sınıfı cpp'de tanımlamanın (anonim isim alanı yok, statik yok) farkı ne olabilir?
Luchian Grigore

6
@LuchianGrigore Durum 2'deki bağlantı sorunları .cpp, aynı ada sahip bir sınıfı tanımlıyor.
Xaqq

8

Bununla ilgili ilginç bir sorun var:

Modüle (çeviri birimi) bir işlev yapmak için staticanahtar sözcük veya adsız kullandığınızı varsayalım namespace, çünkü bu işlev modül tarafından dahili olarak kullanılmak içindir ve modülün dışından erişilemez. (Adsızlar namespace, işlevlerin yanı sıra veri ve tür tanımlarını da dahili yapma avantajına sahiptir).

Zamanla modülünüzün uygulamasının kaynak dosyası büyür ve onu birkaç ayrı kaynak dosyaya bölmek istersiniz, bu da kodu daha iyi organize etmeye, tanımları daha hızlı bulmaya ve bağımsız olarak derlenmeye olanak tanır.

Ama şimdi bir sorunla karşı karşıyasınız: Bu işlevler artık staticmodüle staticdeğil , çünkü aslında modüle değil, kaynak dosyaya (çeviri birimi) başvuruyor . Bu staticmodülün diğer bölümlerinden (nesne dosyalarından) erişilmesine izin vermemeye zorlanıyorsunuz . Ancak bu aynı zamanda modüle artık gizli / özel olmadıkları anlamına da gelir: harici bağlantılara sahip olduklarından, asıl amacınız bu olmayan diğer modüllerden erişilebilirler .

Adsız namespaceda bu sorunu çözmez, çünkü belirli bir kaynak dosyası (çeviri birimi) için de tanımlanmıştır ve dışarıdan erişilemez.

Biri bazı belirtmek olursanız harika olur namespaceise privateait olduğu modül tarafından dahili kullanılmak üzere içindir, onun içinde tanımlanan şey olduğunu. Ama elbette C ++ "modüller" gibi bir konsepte sahip değildir, sadece kaynak dosyalara sıkı sıkıya bağlı "çeviri birimleri".


3
Yine de bir hack ve sınırlı bir çözüm olurdu, ancak dahili statik veya isim alanlı işlevlere sahip cpp dosyalarını 'ana' cpp dosyalarınıza dahil edebilirsiniz. Sonra bu 'uydu' cpp dosyalarını derlemeden çıkarın ve bitirdiniz. İki veya daha fazla 'ana' cpp dosyanız varsa ve ikisi de bu harika işlevi 'uydu' cpp dosyalarından birinden kullanmak istiyorsa tek sorun ...
Sergey

çözüm, özel / korumalı / genel statik işlevlerle kalıtımı kullanmak değil mi?
Ali

C ++ 20, probleminizi çözen modüller sunar.
LF
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.