Mungkin duplikat, tapi tidak mudah untuk mencari ...
Diberikan header seperti:
namespace ns1
{
class MyClass
{
void method();
};
}
Saya telah melihat method()
didefinisikan dalam beberapa cara di file .cpp:
Versi 1:
namespace ns1
{
void MyClass::method()
{
...
}
}
Versi 2:
using namespace ns1;
void MyClass::method()
{
...
}
Versi 3:
void ns1::MyClass::method()
{
...
}
Apakah ada cara yang 'benar' untuk melakukannya? Apakah ada di antara yang 'salah' ini karena tidak semuanya memiliki arti yang sama?
c++
coding-style
namespaces
Mr Boy
sumber
sumber
Jawaban:
Versi 2 tidak jelas dan tidak mudah dipahami karena Anda tidak tahu namespace
MyClass
milik mana dan itu hanya tidak logis (fungsi kelas tidak dalam namespace yang sama?)Versi 1 benar karena ini menunjukkan bahwa di namespace, Anda mendefinisikan fungsi.
Versi 3 juga benar karena Anda menggunakan
::
operator resolusi cakupan untuk merujuk keMyClass::method ()
dalam namespacens1
. Saya lebih suka versi 3.Lihat Namespaces (C ++) . Ini adalah cara terbaik untuk melakukannya.
sumber
namespace N {struct X { void f(); }; X operator==( X const &, X const & ); }
, sekarang di file cpp dengan pernyataan menggunakan Anda dapat mendefinisikan fungsi anggota sebagaivoid X::f() {}
, tetapi jika Anda mendefinisikanX operator==(X const&, X const&)
Anda akan mendefinisikan operator yang berbeda dari yang satu didefinisikan di tajuk (Anda harus menggunakan 1 atau 3 untuk fungsi gratis di sana).5 tahun kemudian dan saya pikir saya akan menyebutkan ini, yang keduanya terlihat bagus dan tidak jahat
sumber
Saya menggunakan versi 4 (di bawah) karena menggabungkan sebagian besar keuntungan dari versi 1 (ketegasan definisi resoective) dan versi 3 (harus secara maksimal eksplisit). Kerugian utama adalah bahwa orang tidak terbiasa tetapi karena saya menganggapnya secara teknis lebih unggul daripada alternatif, saya tidak keberatan.
Versi 4: gunakan kualifikasi penuh menggunakan alias namespace:
Di dunia saya, saya sering menggunakan alias namespace karena semuanya secara eksplisit memenuhi syarat - kecuali tidak bisa (misalnya nama variabel) atau itu adalah titik kustomisasi yang dikenal (misalnya swap () dalam template fungsi).
sumber
outer
daninner
didefinisikan sebagai ruang nama di file header lain sudah?Versi 3 membuat asosiasi antara kelas dan namespace sangat eksplisit dengan mengorbankan lebih banyak pengetikan. Versi 1 menghindari ini tetapi menangkap asosiasi dengan blok. Versi 2 cenderung menyembunyikan ini jadi saya akan menghindari yang itu.
sumber
Panduan Gaya C ++ Google menentukan versi 1 Anda, tanpa lekukan.
sumber
Saya memilih Num.3 (alias versi verbose). Ini lebih banyak mengetik, tetapi maksudnya tepat untuk Anda dan kompilator. Masalah yang Anda posting apa adanya sebenarnya lebih sederhana daripada di dunia nyata. Di dunia nyata, ada cakupan lain untuk definisi, bukan hanya anggota kelas. Definisi Anda tidak terlalu rumit hanya dengan kelas - karena cakupannya tidak pernah dibuka kembali (tidak seperti ruang nama, cakupan global, dll.).
Num.1 ini bisa gagal dengan cakupan selain kelas - apapun yang bisa dibuka kembali. Jadi, Anda dapat mendeklarasikan fungsi baru di namespace menggunakan pendekatan ini, atau inline Anda bisa diganti melalui ODR. Anda akan membutuhkan ini untuk beberapa definisi (khususnya, spesialisasi template).
Num.2 Ini sangat rapuh, terutama dalam basis kode yang besar - saat header dan dependensi bergeser, program Anda akan gagal untuk dikompilasi.
Nomor 3 Ini ideal, tetapi banyak yang harus diketik - apa maksud Anda untuk mendefinisikan sesuatu . Ini persis seperti itu, dan kompilator mulai memastikan Anda tidak membuat kesalahan, definisi tidak selaras dengan deklarasinya, dll ..
sumber
Ternyata itu bukan hanya "masalah gaya pengkodean". Num. 2 menyebabkan kesalahan penautan saat menentukan dan menginisialisasi variabel yang dideklarasikan secara eksternal di file header. Lihat contoh dalam pertanyaan saya. Definisi konstanta dalam namespace di file cpp
sumber
Semua cara sudah benar, dan masing-masing memiliki kelebihan dan kekurangan.
Di versi 1, Anda memiliki keuntungan karena tidak harus menulis namespace di depan setiap fungsi. Kerugiannya adalah Anda akan mendapatkan identitas yang membosankan, terutama jika Anda memiliki lebih dari satu tingkat namespace.
Di versi 2, Anda membuat kode Anda lebih bersih, tetapi jika Anda memiliki lebih dari satu namespace yang diimplementasikan di CPP, seseorang dapat mengakses fungsi dan variabel lainnya secara langsung, membuat namespace Anda tidak berguna (untuk file cpp itu).
Di versi 3, Anda harus mengetik lebih banyak dan garis fungsi Anda mungkin lebih besar dari layar, yang berdampak buruk untuk efek desain.
Ada juga cara lain yang digunakan sebagian orang. Ini mirip dengan versi pertama, tetapi tanpa masalah identifikasi.
Seperti ini:
Terserah Anda untuk memilih mana yang lebih baik untuk setiap situasi =]
sumber
#ifdef
klausa.#define OPEN_NS(X)
saya kira sedikit berguna, tetapi tidak terlalu ... Saya tidak keberatan dengan makro tetapi ini tampaknya sedikit OTT. Saya pikir pendekatan Dietmar Kühl lebih baik untuk ruang nama bersarang.