Keunggulan namespace tanpa nama dibandingkan statis?

130

Bagaimana ruang nama tanpa nama lebih unggul dari statickata kunci?

Nawaz
sumber
Namun, ruang nama yang tidak disebutkan namanya bukan pengganti yang cukup untuk namespace-statis , menurut komite standar. Masih ada beberapa contoh di mana ruang nama yang tidak disebutkan namanya gagal dan hanya staticberfungsi.
legends2k

Jawaban:

134

Anda pada dasarnya merujuk pada bagian §7.3.1.1 / 2 dari Standar C ++ 03,

Penggunaan kata kunci statis tidak digunakan lagi ketika mendeklarasikan objek dalam lingkup namespace; namespace tanpa nama memberikan alternatif yang unggul.

Perhatikan bahwa paragraf ini sudah dihapus dalam C ++ 11. staticfungsi sesuai standar tidak lagi ditinggalkan!

Meskipun demikian, ruang nama yang tidak bernama lebih unggul dari kata kunci statis, terutama karena kata kunci statichanya berlaku untuk deklarasi dan fungsi variabel , bukan untuk tipe yang ditentukan pengguna .

Kode berikut ini valid dalam C ++

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

Tetapi kode ini TIDAK valid:

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

Jadi solusinya adalah, namespace tanpa nama, yang ini,

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

Semoga ini menjelaskan bahwa mengapa unnamed-namespacelebih unggul static.

Juga, perhatikan bahwa penggunaan kata kunci statis tidak digunakan lagi ketika mendeklarasikan objek dalam lingkup namespace (sesuai Standar).

Nawaz
sumber
11
Secara umum, namespace yang tidak disebutkan namanya memungkinkan hubungan eksternal. Itulah yang memungkinkan deklarasi kelas lokal ke terjemahan. Ini juga memungkinkan mis. String tautan eksternal eksternal, untuk digunakan sebagai argumen templat.
Ceria dan hth. - Alf
10
Seperti dicatat oleh Fred Nurk pada jawaban Anda yang lain, tampaknya deprecatedkomentar ini telah dihapus dari C ++ 0x FCD terbaru (n3225).
Matthieu M.
36
Anda menjawab pertanyaan Anda sendiri dan mengucapkan terima kasih kepada diri sendiri: -o
manpreet singh
12
Apa perbedaan dari hanya mendefinisikan kelas dalam cpp (tidak ada namespace anonim, tidak ada statis)?
Luchian Grigore
6
@LuchianGrigore Menautkan masalah dalam kasus 2 .cppmendefinisikan kelas dengan nama yang sama.
Xaqq
8

Ada masalah menarik terkait hal ini:

Misalkan Anda menggunakan statickata kunci atau tidak bernama namespaceuntuk membuat beberapa fungsi internal ke modul (unit terjemahan), karena fungsi ini dimaksudkan untuk digunakan secara internal oleh modul dan tidak dapat diakses di luarnya. (Unnamed namespaces memiliki keuntungan membuat data dan mengetik definisi internal juga, selain fungsi).

Seiring waktu, file sumber implementasi modul Anda tumbuh besar, dan Anda ingin membaginya menjadi beberapa file sumber terpisah, yang akan memungkinkan pengorganisasian kode yang lebih baik, menemukan definisi lebih cepat, dan untuk dikompilasi secara independen.

Tetapi sekarang Anda menghadapi masalah: Fungsi-fungsi itu tidak bisa lagi menjadi staticmodul, karena staticsebenarnya tidak merujuk ke modul , tetapi ke file sumber (unit terjemahan). Anda dipaksa untuk membuatnya agar tidak staticdapat diakses dari bagian lain (file objek) dari modul itu. Tetapi ini juga berarti bahwa mereka tidak lagi tersembunyi / pribadi ke modul: memiliki hubungan eksternal, mereka dapat diakses dari modul lain, yang bukan maksud asli Anda.

Tidak bernama namespacejuga tidak akan menyelesaikan masalah ini, karena juga ditentukan untuk file sumber tertentu (unit terjemahan) dan tidak dapat diakses dari luar.

Akan lebih baik jika seseorang dapat menentukan bahwa beberapa namespaceadalah private, yaitu, apa pun yang didefinisikan di dalamnya, dimaksudkan untuk digunakan secara internal oleh modul yang dimilikinya. Tetapi tentu saja C ++ tidak memiliki konsep seperti "modul", hanya "unit terjemahan", yang terikat erat dengan file sumber.

SasQ
sumber
3
Ini akan menjadi peretasan dan solusi terbatas, tetapi Anda bisa memasukkan file cpp (s) dengan fungsi internal statis atau namespace ke dalam file cpp 'utama' Anda. Kemudian kecualikan file cpp 'satelit' ini dari build dan Anda selesai. Satu-satunya masalah jika Anda memiliki dua atau lebih file cpp 'utama' dan mereka berdua ingin menggunakan fungsi keren dari salah satu file cpp 'satelit' ...
Sergey
tidak menggunakan warisan dengan privat / terproteksi / publik dengan fungsi statis solusinya?
Ali
C ++ 20 memperkenalkan modul, yang memecahkan masalah Anda.
LF
4

Standar C ++ membaca di bagian 7.3.1.1 Ruang nama yang tidak disebutkan namanya, paragraf 2:

Penggunaan kata kunci statis tidak digunakan lagi saat mendeklarasikan objek dalam lingkup namespace, unnamed-namespace memberikan alternatif yang unggul.

Statis hanya berlaku untuk nama objek, fungsi, dan serikat anonim, bukan untuk mengetik deklarasi.

Salgar
sumber
5
Tidak, tidak. Draf lakukan. Dan draft lain segera setelah itu mengembalikan perubahan konyol ini.
underscore_d