Yanıtlar:
Bir ad alanı diğer adı, daha uzun ve farklı bir adla uzun bir ad alanı adını belirtmenin uygun bir yoludur.
Örnek olarak, Boost'un uBLAS'ındaki sayısal vektörleri bir using namespace
yönerge olmadan kullanmak istediğinizi varsayalım . Her zaman tam ad alanının belirtilmesi zahmetlidir:
boost::numeric::ublas::vector<double> v;
Bunun yerine, için bir takma ad tanımlayabilirsiniz boost::numeric::ublas
- diyelim ki bunu sadece kısaltmak istiyoruz ublas
:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
Oldukça basit bir şekilde, #define çalışmaz.
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
İyi derler. Ad alanı / sınıf adı çarpışmaları etrafında çalışmanıza izin verir.
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
Son satırda "Hmm: Oops" bir derleme hatasıdır. Ön işlemci Nope :: Oops olarak değiştirir, ancak Nope zaten bir sınıf adıdır.
Bu konu hakkında daha fazla bilgi http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
Her şey bir Looong ad alanı adı için bir takma ad seçmekle ilgilidir, örneğin:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Sonra daha sonra,
typedef SHORT::mytype
onun yerine
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
Bu sözdizimi yalnızca ad alanları için çalışır, sınıfları içeremez, namespace NAME =
Ayrıca, ad alanı diğer adlarının ve kullanım yönergelerinin derleme zamanında değil, çalışma zamanında çözüldüğüne dikkat edin. (Daha spesifik olarak, ikisi de geçerli kapsamda veya üst kapsamlarından herhangi birinde belirli bir sembol bulamazsa derleyiciye adları çözerken başka nereye bakacağını söylemek için kullanılan araçlardır.) Örneğin, bunların hiçbiri derlemek:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
Şimdi, meraklı bir zihin, constexpr
değişkenlerin derleme zamanında da kullanıldığını fark etmiş olabilir ve bunların bir takma adla mı yoksa bir direktifle mi kullanıldığını merak edebilir. Bildiğim kadarıyla, bu konuda yanlış olabilsem de yapamazlar. Farklı ad alanlarında aynı adlı değişkenlerle çalışmanız ve bunlar arasında dinamik olarak seçim yapmanız gerekiyorsa, referanslar veya işaretçiler kullanmanız gerekir.
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
Yukarıdakilerin yararlılığı sınırlı olabilir, ancak amaca hizmet etmelidir.
(Yukarıda kaçırmış olabileceğim herhangi bir yazım hatası için özür dilerim.)
Ad alanı, ad çakışmalarını önlemek için kullanılır.
Örneğin:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
Artık ad alanı sayesinde tamamen farklı ve ayrı olan iki sınıf ad çubuğunuz var.
Gösterdiğiniz "ad alanını kullanma", bu ad alanında sınıfları kullanmak için ad alanını belirtmenize gerek kalmamasıdır. yani std :: string dize olur.