Saya menemukan baris kode ini di kelas yang harus saya ubah:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
dan saya tidak tahu apa sebenarnya arti dari usus besar ganda yang diawali dengan nama kelas. Tanpa itu saya akan membaca: deklarasi tmpCo
sebagai penunjuk ke objek kelas Configuration
... tapi usus besar bersebelahan membingungkan saya.
Saya juga menemukan:
typedef ::config::set ConfigSet;
c++
syntax
namespaces
scope-resolution
global-namespace
rmbianchi
sumber
sumber
::
berarti telanjang merujuk variabel dari namespace global / anonim.Jawaban:
Ini memastikan bahwa resolusi muncul dari namespace global, alih-alih dimulai dari namespace tempat Anda berada saat ini. Misalnya, jika Anda memiliki dua kelas berbeda yang disebut
Configuration
sebagai:Pada dasarnya, ini memungkinkan Anda untuk melintasi ke namespace global karena nama Anda mungkin akan dihancurkan oleh definisi baru di dalam namespace lain, dalam hal ini
MyApp
.sumber
::Configuration::doStuff(...)
::
di antara dua istilah mengacu pada namespace atau kelas dan anggotanya. Tapi bagaimana dengan yang ke-1?The
::
operator disebut operator lingkup-resolusi dan tidak hanya itu, menyelesaikan lingkup. Jadi, dengan mengawali tipe-nama dengan ini, ia memberitahu kompiler Anda untuk mencari di namespace global untuk tipe tersebut.Contoh:
sumber
Sudah banyak jawaban masuk akal. Saya akan menambahkan analogi yang dapat membantu beberapa pembaca.
::
bekerja sangat mirip dengan pemisah direktori filesystem '/
', ketika mencari jalur Anda untuk program yang ingin Anda jalankan. Mempertimbangkan:Ini sangat eksplisit - hanya dapat dieksekusi di lokasi yang tepat di pohon sistem file yang dapat cocok dengan spesifikasi ini, terlepas dari PATH yang berlaku. Demikian pula...
... sama eksplisit di C ++ namespace "tree".
Berbeda dengan jalur absolut seperti itu, Anda dapat mengonfigurasi shell UNIX yang baik (misalnya zsh ) untuk menyelesaikan jalur relatif di bawah direktori Anda saat ini atau elemen apa pun dalam
PATH
variabel lingkungan Anda , jadi jikaPATH=/usr/bin:/usr/local/bin
, dan Anda berada "di"/tmp
, maka ...... akan dengan senang hati lari
/tmp/X11/xterm
jika ditemukan, yang lain/usr/bin/X11/xterm
, yang lain/usr/local/bin/X11/xterm
. Demikian pula, katakanlah Anda berada di namespace bernamaX
, dan "using namespace Y
" berlaku, lalu ...... dapat ditemukan di salah
::X::std::cout
,::std::cout
,::Y::std::cout
, dan tempat-tempat mungkin lain karena argumen-dependent lookup (ADL, alias Koenig lookup). Jadi, hanya::std::cout
benar-benar eksplisit tentang objek yang Anda maksud, tetapi untungnya tidak ada orang waras yang pernah membuat kelas / struct atau namespace mereka sendiri yang disebut "std
", atau apa pun yang disebut "cout
", jadi dalam praktiknya menggunakan hanyastd::cout
baik-baik saja.Perbedaan yang patut diperhatikan :
1) shell cenderung menggunakan pertandingan pertama menggunakan urutan
PATH
, sedangkan C ++ memberikan kesalahan kompilator ketika Anda telah ambigu.2) Dalam C ++, nama tanpa lingkup utama dapat dicocokkan di namespace saat ini, sementara sebagian besar shell UNIX hanya melakukan itu jika Anda memasukkannya ke
.
dalamPATH
.3) C ++ selalu mencari namespace global (seperti memiliki
/
Anda secara implisitPATH
).Diskusi umum tentang ruang nama dan kesederhanaan simbol
Menggunakan
::abc::def::...
"jalur" absolut kadang-kadang bisa berguna untuk mengisolasi Anda dari ruang nama lain yang Anda gunakan, bagian dari tetapi tidak benar-benar memiliki kontrol atas konten, atau bahkan perpustakaan lain yang juga menggunakan kode klien perpustakaan Anda. Di sisi lain, ini juga memasangkan Anda dengan lebih erat ke lokasi simbol "absolut" yang ada, dan Anda kehilangan keuntungan dari pencocokan tersirat dalam ruang nama: lebih sedikit sambungan, lebih mudah mobilitas kode antara ruang nama, dan kode sumber yang lebih ringkas dan mudah dibaca .Seperti banyak hal, ini adalah tindakan penyeimbang. C ++ Standar menempatkan banyak pengidentifikasi bawah
std::
yang kurang "unik" daricout
, bahwa programmer mungkin menggunakan untuk sesuatu yang sama sekali berbeda dalam kode mereka (misalnyamerge
,includes
,fill
,generate
,exchange
,queue
,toupper
,max
). Dua perpustakaan non-Standar yang tidak terkait memiliki peluang yang jauh lebih tinggi untuk menggunakan pengidentifikasi yang sama karena para penulis umumnya tidak atau kurang menyadari satu sama lain. Dan perpustakaan - termasuk perpustakaan C ++ Standard - mengubah simbol mereka dari waktu ke waktu. Semua ini berpotensi menciptakan ambiguitas ketika mengkompilasi ulang kode lama, terutama ketika sudah ada banyak penggunaanusing namespace
s: hal terburuk yang dapat Anda lakukan dalam ruang ini adalah memungkinkanusing namespace
ada di header untuk menghindari lingkup header, sehingga sejumlah besar kode klien langsung dan tidak langsung tidak dapat membuat keputusan sendiri tentang ruang nama mana yang akan digunakan dan bagaimana mengelola ambiguitas.Jadi, yang terdepan
::
adalah salah satu alat di kotak alat programmer C ++ untuk secara aktif mengacaukan bentrokan yang diketahui, dan / atau menghilangkan kemungkinan ambiguitas di masa depan ....sumber
::
adalah operator resolusi ruang lingkup. Ini digunakan untuk menentukan ruang lingkup sesuatu.Misalnya,
::
sendiri adalah ruang lingkup global, di luar semua ruang nama lainnya.some::thing
dapat diartikan dengan salah satu cara berikut:some
adalah namespace (dalam lingkup global, atau lingkup luar dari yang sekarang) danthing
merupakan tipe , fungsi , objek atau namespace bersarang ;some
adalah kelas yang tersedia dalam ruang lingkup saat ini danthing
merupakan objek anggota , fungsi atau jenis darisome
kelas;some
bisa menjadi tipe dasar dari tipe saat ini (atau tipe saat ini sendiri) danthing
kemudian menjadi salah satu anggota kelas ini, tipe , fungsi atau objek .Anda juga dapat memiliki ruang lingkup bersarang, seperti pada
some::thing::bad
. Di sini setiap nama bisa berupa tipe, objek, atau namespace. Selain itu, yang terakhirbad
,, juga bisa menjadi fungsi. Yang lain tidak bisa, karena fungsi tidak dapat mengekspos apa pun dalam lingkup internal mereka.Jadi, kembali ke contoh Anda,
::thing
bisa jadi hanya sesuatu dalam lingkup global: tipe, fungsi, objek, atau namespace.Cara Anda menggunakannya menyarankan (digunakan dalam deklarasi pointer) bahwa itu adalah tipe dalam lingkup global.
Saya harap jawaban ini lengkap dan cukup benar untuk membantu Anda memahami resolusi ruang lingkup.
sumber
class some { protected: int thing; }; class some_ext : public some { float thing; void action(){ some::thing = 42; thing = 666; } };
Inisome
adalah kelas dasarsome_ext
dan ketika Anda menulissome::thing
ke fungsi anggota some_ext, itu berartithing
objek menjadi tipe dasarsome
. Tanpasome::
,thing
sendirian berartithing
dalam ruang lingkup terdekat, yaitusome_ext::thing
. Apakah lebih jelas?::
digunakan untuk menautkan sesuatu (variabel, fungsi, kelas, typedef dll ...) ke namespace, atau ke kelas.jika tidak ada sisi kiri sebelumnya
::
, maka itu menggarisbawahi fakta bahwa Anda menggunakan namespace global.misalnya:
::doMyGlobalFunction();
sumber
disebut operator resolusi lingkup, Nama global tersembunyi dapat disebut menggunakan operator resolusi lingkup ::
Misalnya;
sumber
(Jawaban ini sebagian besar untuk para googler, karena OP sudah menyelesaikan masalahnya.) Arti dari prepended
::
operator ruang lingkup yang dijelaskan sebelumnya - telah dijelaskan dalam jawaban lain, tetapi saya ingin menambahkan mengapa orang menggunakannya.Artinya adalah "mengambil nama dari namespace global, bukan yang lain". Tetapi mengapa ini harus dieja secara eksplisit?
Gunakan case - namespace clash
Ketika Anda memiliki nama yang sama di namespace global dan di namespace lokal / bersarang, yang lokal akan digunakan. Jadi, jika Anda menginginkan yang global, tambahkan dengan
::
. Kasus ini dijelaskan dalam jawaban @ Wyatt Anderson, lihat contohnya.Use case - menekankan fungsi non-anggota
Saat Anda menulis fungsi anggota (metode), panggilan ke fungsi anggota lainnya dan panggilan ke fungsi non-anggota (gratis) mirip:
Tetapi mungkin terjadi bahwa
Twist
ini adalah fungsi sister classA
, danBend
merupakan fungsi bebas. Artinya,Twist
bisa menggunakan dan memodifikasim_couner
danBend
tidak bisa. Jadi, jika Anda ingin memastikan bahwam_counter
0 tetap, Anda harus memeriksaTwist
, tetapi Anda tidak perlu memeriksaBend
.Jadi untuk membuatnya lebih jelas, orang bisa menulis
this->Twist
untuk menunjukkan kepada pembaca yangTwist
merupakan fungsi anggota atau menulis::Bend
untuk menunjukkan yangBend
gratis. Atau keduanya. Ini sangat berguna ketika Anda melakukan atau merencanakan refactoring.sumber
::
adalah operator mendefinisikan namespace.Misalnya, jika Anda ingin menggunakan cout tanpa menyebutkan
using namespace std;
kode Anda, Anda menulis ini:Ketika tidak ada namespace yang disebutkan, maka dikatakan bahwa kelas milik global namespace.
sumber
"::" mewakili operator resolusi lingkup. Fungsi / metode yang memiliki nama yang sama dapat didefinisikan dalam dua kelas yang berbeda. Untuk mengakses metode operator resolusi ruang lingkup kelas tertentu digunakan.
sumber