Saya beralih dari C ++ ke Java dan C # dan berpikir penggunaan namespace / paket jauh lebih baik di sana (terstruktur dengan baik). Kemudian saya kembali ke C ++ dan mencoba menggunakan namespace dengan cara yang sama tetapi sintaks yang diperlukan sangat buruk di dalam file header.
namespace MyCompany
{
namespace MyModule
{
namespace MyModulePart //e.g. Input
{
namespace MySubModulePart
{
namespace ...
{
public class MyClass
Hal berikut juga tampak aneh bagi saya (untuk menghindari indentasi yang dalam):
namespace MyCompany
{
namespace MyModule
{
namespace MyModulePart //e.g. Input
{
namespace MySubModulePart
{
namespace ...
{
public class MyClass
{
Apakah ada cara yang lebih singkat untuk mengungkapkan hal di atas? Saya kehilangan sesuatu seperti
namespace MyCompany::MyModule::MyModulePart::...
{
public class MyClass
Memperbarui
Ok, ada yang bilang konsep penggunaan di Java / C # dan C ++ berbeda. Betulkah? Saya pikir pemuatan kelas (dinamis) bukan satu-satunya tujuan untuk ruang nama (ini adalah perspektif beralasan yang sangat teknis). Mengapa saya tidak menggunakannya untuk keterbacaan dan penataan, misalnya memikirkan "IntelliSense".
Saat ini, tidak ada logika / perekat antara namespace dan apa yang dapat Anda temukan di sana. Java dan C # melakukan ini jauh lebih baik ... Mengapa menyertakan <iostream>
dan memiliki namespace std
? Oke, jika Anda mengatakan logika harus bergantung pada tajuk untuk menyertakan, mengapa #include tidak menggunakan sintaks ramah "IntelliSense" seperti #include <std::io::stream>
or <std/io/stream>
? Saya pikir strukturisasi yang hilang di libs default adalah salah satu kelemahan C ++ dibandingkan dengan Java / C #.
Jika keunikan untuk avid konflik adalah satu Titik (yang juga merupakan titik C # dan Java), ide yang bagus adalah menggunakan nama proyek atau nama perusahaan sebagai namespace, bukan begitu?
Di satu sisi dikatakan C ++ adalah yang paling fleksibel ... tetapi semua orang berkata "jangan lakukan ini"? Menurut saya C ++ dapat melakukan banyak hal tetapi memiliki sintaksis yang mengerikan bahkan untuk hal yang paling mudah dalam banyak kasus dibandingkan dengan C #.
Perbarui 2
Sebagian besar pengguna mengatakan tidak masuk akal untuk membuat sarang yang lebih dalam dari dua Tingkat. Ok, jadi bagaimana dengan Windows :: UI :: Xaml dan Windows :: UI :: Xaml :: Controls :: Primitives namespaces dalam pengembangan Win8? Saya pikir penggunaan namespace Microsoft masuk akal dan memang lebih dalam dari hanya 2 Level. Saya pikir perpustakaan / proyek yang lebih besar membutuhkan penyarangan yang lebih dalam (saya benci nama kelas seperti ExtraLongClassNameBecauseEveryThingIsInTheSameNameSpace ... maka Anda juga dapat memasukkan semuanya ke dalam namespace global.)
Perbarui 3 - Kesimpulan
Sebagian besar mengatakan "jangan lakukan itu", tetapi ... bahkan peningkatan memiliki tingkat yang lebih dalam daripada satu atau dua tingkat. Ya, ini adalah perpustakaan tetapi: Jika Anda menginginkan kode yang dapat digunakan kembali - perlakukan kode Anda sendiri seperti perpustakaan yang akan Anda berikan kepada orang lain. Saya juga menggunakan penyarangan yang lebih dalam untuk tujuan penemuan menggunakan ruang nama.
sumber
namespace
kata kunci?Jawaban:
C ++ 17 mungkin menyederhanakan definisi namespace bersarang:
setara dengan
Lihat (8) di halaman namespace di cppreference:
http://en.cppreference.com/w/cpp/language/namespace
sumber
/std:c++latest
/std:c++latest
Visual Studio 2015 dan juga menggunakan Boost, Anda mungkin mengalami kesalahan kompiler yang sangat mistis saat Anda menyertakan beberapa header Boost. Saya menghadapi masalah ini seperti yang dijelaskan dalam pertanyaan StackOverflow iniUntuk menghindari indentasi yang sangat dalam, saya biasanya melakukannya dengan cara ini:
sumber
clang-format
tidak dapat memformatnya saat Anda menampilkan clang.llvm.org/docs/ClangFormatStyleOptions.html (NamespaceIndentation)Saya sepenuhnya mendukung jawaban peterchen tetapi ingin menambahkan sesuatu yang menjawab bagian lain dari pertanyaan Anda.
Mendeklarasikan namespaces adalah salah satu kasus yang sangat jarang terjadi di C ++ di mana saya sebenarnya suka penggunaan
#define
s.Ini juga menghilangkan kebutuhan akan komentar di dekat tanda kurung kurawal tutup ruang nama (Apakah Anda pernah menggulir ke bawah ke bagian bawah file sumber besar dan mencoba menambahkan / menghapus / menyeimbangkan tanda kurung yang tidak ada komentar tentang tanda kurung yang menutup cakupan yang mana? Tidak menyenangkan .).
Jika Anda ingin meletakkan semua deklarasi namespace dalam satu baris, Anda juga dapat melakukannya dengan sedikit keajaiban preprocessor (sangat jelek):
Sekarang Anda bisa melakukan ini:
Untuk bersarang lebih dari tiga level, Anda harus menambahkan makro pembantu hingga jumlah yang diinginkan.
sumber
#define
, saya cukup terkesan dengan keajaiban preprocessor itu ... hanya jika saya tidak perlu menambahkan makro pembantu tambahan untuk penyarangan yang lebih dalam ... yah, saya tidak akan menggunakannya, jadi .. .Namespace C ++ digunakan untuk mengelompokkan antarmuka, bukan untuk membagi komponen atau mengungkapkan divisi politik.
Standar berusaha keras untuk melarang penggunaan namespace seperti Java. Misalnya, alias namespace menyediakan cara untuk dengan mudah menggunakan nama namespace yang bertingkat atau panjang.
Tapi
namespace nsc {}
kemudian akan menjadi kesalahan, karena namespace hanya dapat didefinisikan menggunakan nama-namespace-aslinya . Pada dasarnya standar membuat hal-hal mudah bagi pengguna perpustakaan seperti itu tetapi sulit bagi pelaksana . Ini membuat orang enggan menulis hal-hal seperti itu tetapi mengurangi efeknya jika mereka melakukannya.Anda harus memiliki satu namespace per antarmuka yang ditentukan oleh sekumpulan kelas dan fungsi terkait. Sub-antarmuka internal atau opsional mungkin masuk ke ruang nama bersarang. Tetapi lebih dari dua tingkat seharusnya menjadi tanda bahaya yang sangat serius.
Pertimbangkan untuk menggunakan karakter garis bawah dan awalan pengenal jika
::
operator tidak diperlukan.sumber
company::division
overcompany_division
?Tidak, dan tolong jangan lakukan itu.
Tujuan utama namespace adalah menyelesaikan konflik di namespace global.
Tujuan sekunder adalah singkatan lokal dari simbol; misalnya
UpdateUI
metode kompleks dapat menggunakanusing namespace WndUI
untuk menggunakan simbol yang lebih pendek.Saya menggunakan proyek 1.3MLoc, dan satu-satunya namespace yang kami miliki adalah:
#import
dan#include windows.h
)ModuleDetailHereBeTygers
ruang nama di lib hanya header)Dalam proyek ini, nama kelas, dll. Menggunakan kode "wilayah" dua atau tiga huruf (misalnya,
CDBNode
bukanDB::CNode
). Jika Anda lebih suka yang terakhir, ada ruang untuk namespace "publik" tingkat kedua, tapi tidak lebih.Enum khusus kelas, dll. Dapat menjadi anggota kelas tersebut (meskipun saya setuju ini tidak selalu baik, dan terkadang sulit untuk mengatakan apakah Anda harus)
Namespace "perusahaan" juga jarang dibutuhkan, kecuali jika Anda mengalami masalah besar dengan pustaka pihak ketiga yang didistribusikan sebagai biner, jangan berikan namespace mereka sendiri, dan tidak dapat dengan mudah dimasukkan ke dalamnya (mis. Dalam biner distribusi). Namun, menurut pengalaman saya, memaksa mereka ke dalam namespace jauh lebih mudah dilakukan.
[sunting] Sesuai pertanyaan tindak lanjut Stegi:
Maaf jika saya tidak cukup jelas: Dua level bukanlah batas yang sulit, dan lebih banyak tidak buruk secara intrinsik. Saya hanya ingin menunjukkan bahwa Anda jarang membutuhkan lebih dari dua, dari pengalaman saya, bahkan pada basis kode yang besar. Bersarang lebih dalam atau lebih dangkal adalah pengorbanan.
Sekarang, kasus Microsoft bisa dibilang berbeda. Agaknya tim yang jauh lebih besar, dan semua kodenya adalah perpustakaan.
Saya berasumsi Microsoft meniru di sini keberhasilan Pustaka .NET, di mana ruang nama berkontribusi pada penemuan pustaka yang luas. (.NET memiliki sekitar 18000 jenis.)
Saya selanjutnya akan berasumsi bahwa ada simbol (urutan besarnya) yang optimal dalam namespace. katakanlah, 1 tidak masuk akal, 100 terdengar benar, 10000 jelas terlalu banyak.
TL; DR: Ini tradeoff, dan kami tidak memiliki angka pasti. Bermain aman, jangan berlebihan ke segala arah. Kalimat "Jangan lakukan itu" hanya berasal dari "Kamu bermasalah dengan itu, aku punya masalah dengan itu, dan aku tidak melihat alasan mengapa kamu membutuhkannya.".
sumber
Constants
, lalu membuat namespace bersarang dengan nama yang sesuai untuk mengkategorikan konstanta; jika perlu, saya kemudian menggunakan ruang nama lebih lanjut untuk mencegah benturan nama. IniConstants
namespace sendiri terkandung dalam menangkap semua namespace untuk kode sistem program, dengan nama sepertiSysData
. Hal ini menciptakan nama lengkap memenuhi syarat yang mengandung tiga atau empat ruang nama (sepertiSysData::Constants::ErrorMessages
,SysData::Constants::Ailments::Bitflags
, atauSysData::Defaults::Engine::TextSystem
).using
arahan untuk memasukkan nama yang sesuai, meminimalkan kemungkinan nama yang saling bertentangan. Saya merasa itu meningkatkan keterbacaan, dan membantu mendokumentasikan ketergantungan blok kode yang diberikan. Terlepas dari konstanta, saya cenderung mencoba dan menyimpannya di dua ruang nama jika memungkinkan (sepertiSysData::Exceptions
danSysData::Classes
).Berikut kutipan dari dokumen Lzz (Lazy C ++):
Tentu saja kualitas sumber yang bergantung pada alat semacam itu masih bisa diperdebatkan ... Saya akan mengatakan ini lebih merupakan keingintahuan, menunjukkan bahwa penyakit sintaksis yang disebabkan oleh C ++ dapat mengambil banyak bentuk (saya juga punya milik saya ...)
sumber
Kedua standar (C ++ 2003 dan C ++ 11) sangat eksplisit bahwa nama namespace adalah pengenal. Artinya, header bertingkat eksplisit diperlukan.
Kesan saya bahwa ini bukan masalah besar untuk memungkinkan penempatan pengenal yang memenuhi syarat selain nama sederhana dari namespace, tetapi untuk beberapa alasan hal ini tidak diperbolehkan.
sumber
Makalah ini membahas subjek dengan cukup baik: Namespace Paper
Yang pada dasarnya intinya ini. Semakin panjang ruang nama Anda, semakin besar kemungkinan orang akan menggunakan
using namespace
arahan tersebut.Jadi melihat kode berikut, Anda dapat melihat contoh di mana ini akan merugikan Anda:
Kode ini akan dikompilasi dengan baik, namun, jika Anda menghapus komentar pada baris
//using namespace def;
maka namespace "pengujian" akan menjadi ambigu dan Anda akan mengalami benturan penamaan. Ini berarti basis kode Anda dapat berubah dari stabil menjadi tidak stabil dengan menyertakan pustaka pihak ketiga.Di C #, bahkan jika Anda menggunakan
using abc;
danusing def;
kompilator dapat mengenali itutesting::myClass
atau bahkanmyClass
hanya diabc::testing
namespace, tetapi C ++ tidak akan mengenali ini dan itu terdeteksi sebagai tabrakan.sumber
Ya, Anda harus melakukannya seperti
Namun, Anda mencoba menggunakan ruang nama dengan cara yang tidak seharusnya digunakan. Memeriksa pertanyaan ini , mungkin Anda akan merasa berguna.
sumber
Anda dapat menggunakan sintaks ini:
Perhatikan bahwa sintaks ini valid bahkan di C ++ 98 dan hampir mirip dengan yang sekarang tersedia di C ++ 17 dengan definisi namespace bertingkat .
Selamat bersenang-senang!
Sumber:
sumber
[EDIT:]
Karena c ++ 17 namespace bersarang didukung sebagai fitur bahasa standar ( https://en.wikipedia.org/wiki/C%2B%2B17 ). Untuk saat ini, fitur ini tidak didukung di g ++ 8, tetapi dapat ditemukan di kompiler clang ++ 6.0.
[KESIMPULAN:]
Gunakan
clang++6.0 -std=c++17
sebagai perintah kompilasi default Anda. Maka semuanya akan bekerja dengan baik - dan Anda akan dapat mengkompilasinyanamespace OuterNS::InnerNS1::InnerNS2 { ... }
dalam file Anda.[ASLI JAWABAN:]
Karena pertanyaan ini agak lama, saya anggap Anda sudah pindah. Tetapi untuk orang lain, yang masih mencari jawaban, saya datang dengan ide berikut:
(Bolehkah saya memasang iklan Emacs di sini :)?) Mengirim gambar jauh lebih mudah, dan lebih mudah dibaca, daripada sekadar kode pos. Saya tidak bermaksud untuk memberikan jawaban penuh dari semua kasus sudut, saya hanya bermaksud untuk memberikan beberapa inspirasi. (Saya sepenuhnya mendukung C # dan merasa bahwa dalam banyak kasus C ++ harus mengadopsi beberapa fitur OOP, karena C # populer terutama karena perbandingan kemudahan penggunaan).
sumber