İlk olarak, bazı terminoloji:
- kullanım beyanı :
using std::vector;
- kullanma yönergesi :
using namespace std;
Bir başlık dosyasında genel kapsamda kullanılmadıkları sürece kullanma yönergelerini kullanmanın iyi olduğunu düşünüyorum . Yani sahip olmak
using namespace std;
.cpp dosyanız gerçekten bir sorun değildir ve eğer ortaya çıkarsa, tamamen sizin kontrolünüzdedir (ve hatta istenirse belirli blokları kapsayabilir). Kodu bir dizi std::niteleyici ile karıştırmak için özel bir neden göremiyorum - bu sadece bir grup görsel gürültüye dönüşüyor. Bununla birlikte, stdkodunuzda ad alanından bir grup ad kullanmıyorsanız , yönergeyi atlamakta da bir sorun görmüyorum. Bu bir totolojidir - direktif gerekli değilse, kullanmaya gerek yoktur.
Benzer şekilde, ad alanındaki belirli türler için birkaç kullanma bildirimi ( kullanma yönergeleri yerine ) ile stdidare edebiliyorsanız, o zaman yalnızca bu belirli adları mevcut ad alanına getirmemeniz için hiçbir neden yoktur. Aynı şekilde, tek bir kullanım yönergesi de işe yarayacaksa, 25 veya 30 kullanım bildirimine sahip olmanın çılgınca ve defter tutma zahmeti olacağını düşünüyorum.
Ayrıca , using-bildirimi kullanmanız gereken zamanlar olduğunu da unutmamak gerekir . Scott Meyers'in "Madde 25: Etkili C ++, Üçüncü Sürüm'den atmasız bir takas için desteği düşünün" konusuna bakın. Genel, şablonlu bir işleve sahip olmak için, parametreleştirilmiş bir tür için 'en iyi' takas yöntemini kullanmak için, kullanım bildiriminden ve bağımsız değişkene bağlı aramadan (ADL veya Koenig araması olarak da bilinir) yararlanmanız gerekir:
template< typename T >
void foo( T& x, T& y)
{
using std::swap; // makes std::swap available in this function
// do stuff...
swap( x, y); // will use a T-specific swap() if it exists,
// otherwise will use std::swap<T>()
// ...
}
Sanırım ad alanlarından önemli ölçüde yararlanan çeşitli diller için ortak deyimlere bakmalıyız. Örneğin, Java ve C # büyük ölçüde ad alanlarını kullanır (muhtemelen C ++ 'dan daha fazla). Ad alanları içindeki adların bu dillerde kullanılmasının en yaygın yolu, onları bir using-yönergesinin eşdeğeri ile toplu halde mevcut kapsama getirmektir. Bu, yaygın sorunlara yol açmaz ve birkaç kez sorun olduğu durumlarda, söz konusu isimlerle tam nitelikli isimlerle veya takma adlarla işlenerek bir 'istisna' temelinde ele alınır - tıpkı C ++ 'da yapılabileceği gibi.
Herb Sutter ve Andrei Alexandrescu, C ++ Coding Standards: 101 Rules, Guidelines ve Best Practices adlı kitabının "Madde 59: Ad alanı kullanımlarını bir başlık dosyasına veya bir #include'dan önce yazmayın" adlı kitabında şöyle derler:
Kısaca: Yönergelerden sonra uygulama dosyalarınızda bildirimleri ve yönergeleri özgürce kullanarak ad alanını kullanabilir ve kullanmalısınız #includeve bu konuda iyi hissetmelisiniz. Aksine tekrarlanan iddialara rağmen, bildirimleri ve yönergeleri kullanan ad alanı kötü değildir ve ad alanlarının amacını bozmazlar. Aksine, ad alanlarını kullanılabilir kılan şey onlardır.
Stroupstrup, "The C ++ Programming Language, Third Edition" da "Global isim alanını kirletmeyin" şeklinde sıklıkla alıntılanır. Aslında bunu söylüyor (C.14 [15]), ancak C.10.1 bölümüne atıfta bulunarak şöyle diyor:
Bir kullanım bildirimi yerel bir kapsama bir ad ekler. Bir kullanma yönergesi sağlamaz; yalnızca bildirildikleri kapsamdaki adları erişilebilir kılar. Örneğin:
namespaceX {
int i , j , k ;
}
int k ;
void f1()
{
int i = 0 ;
using namespaceX ; // make names from X accessible
i++; // local i
j++; // X::j
k++; // error: X::k or global k ?
::k ++; // the global k
X::k ++; // X’s k
}
void f2()
{
int i = 0 ;
using X::i ; // error: i declared twice in f2()
using X::j ;
using X::k ; // hides global k
i++;
j++; // X::j
k++; // X::k
}
Yerel olarak beyan edilen bir isim (ya sıradan bir beyanname ile ya da bir kullanım beyanı ile beyan edilen) aynı isimdeki yerel olmayan beyanları gizler ve ismin herhangi bir yasadışı aşırı yüklemesi beyan noktasında tespit edilir.
İçin belirsizlik hatası Not k++içinde
f1(). Global adlar, global kapsamda erişilebilir hale getirilen ad alanlarındaki adlara tercih edilmez. Bu, yanlışlıkla yapılan ad çatışmalarına karşı önemli koruma sağlar ve - daha da önemlisi - küresel ad alanını kirletmenin hiçbir avantajının olmamasını sağlar.
Birçok isim bildiren kütüphaneler, kullanım yönergeleri aracılığıyla erişilebilir hale getirildiğinde, kullanılmayan isimlerin çatışmalarının hata olarak görülmemesi önemli bir avantajdır.
...
Geleneksel C ve C ++ programlarına kıyasla ad alanlarını kullanan yeni programlarda global adların kullanımında radikal bir düşüş görmeyi umuyorum. Ad alanlarının kuralları, küresel adların "tembel" bir kullanıcısına, küresel kapsamı kirletmemeye özen gösteren birine göre hiçbir avantaj sağlamayacak şekilde özel olarak hazırlanmıştır.
Ve 'küresel isimlerin tembel bir kullanıcısı' ile aynı avantaja nasıl sahip olunur? Bir ad alanındaki adları güvenli bir şekilde geçerli kapsam için kullanılabilir kılan using-yönergesinden yararlanarak .
Bir ayrım var Not o - isimleri stdbir kullanma-direktifi doğru kullanımı ile kapsamı hazır ad (sonra yönergesini koyarak #includesetmez) değil genel ad alanını kirletmektedir. Sadece bu isimleri kolayca ve çatışmalara karşı korumayı sürdürüyor.