Namespaces
Although
names can be nested inside classes, the names of global functions, global
variables, and classes are still in a single global name space. The 
static
keyword gives you some control over this by allowing you to give variables and
functions internal linkage (make them file static).
But in a large project, lack of control over the global name space can cause
problems. To solve these problems for classes, vendors often create long
complicated names that are unlikely to clash, but then you’re stuck
typing those names. (A 
typedef
is often used to simplify this.) It’s not an elegant, language-supported
solution.
 You
can subdivide the global name space into more manageable pieces using the 
namespace
feature
of C++.
[35]
The 
namespace
keyword, like 
class,
struct,
enum,
and 
union,
puts the names of its members in a distinct space. While the other keywords
have additional purposes, the creation of a new name space is the only purpose
for 
namespace. 
Creating
a namespace
The
creation of a namespace is notably similar to the creation of a 
class: 
namespace MyLib {
  // DeclarationsThis
produces a new 
namespace
containing the enclosed declarations. There are significant differences with 
class,
struct,
union
and 
enum,
however:
 
- 	A
namespace
definition can only appear at the global scope, but namespaces can be nested
within each other.
- 	No
terminating semicolon is necessary after the closing brace of a 
namespace
definition.
- 	A
namespace
definition
can be “continued” over multiple header files using a syntax that
would appear to be a redefinition for a class:
 
//: C10:Header1.h
namespace MyLib {
  extern int x;
  void f();
  // ...
} ///:~
//: C10:Header2.h
// Add more names to MyLib
namespace MyLib { // NOT a redefinition!
  extern int y;
  void g();
  // ...
- 	A
namespace
name
can be 
aliased
to another name, so you don’t have to type an unwieldy name created by a
library vendor:
 
namespace BobsSuperDuperLibrary {
  class Widget { /* ... */ };
  class Poppit { /* ... */ };
  // ...
}
// Too much to type! I’ll alias it:namespace
Bob = BobsSuperDuperLibrary;
 
- 	You
cannot create an instance of a namespace as you can with a class.
Unnamed
namespaces
Each
translation unit contains an unnamed namespace that
you can add to by saying 
namespace
without an identifier:
 
namespace {
  class Arm  { /* ... */ };
  class Leg  { /* ... */ };
  class Head { /* ... */ };
  class Robot {
    Arm arm[4];
    Leg leg[16];
    Head head[3];
    // ...
  } xanthan;
  int i, j, k;The
names in this space are automatically available in that translation unit
without qualification. It is guaranteed that an unnamed space is unique for
each translation unit. If you put local names in an unnamed namespace, you
don’t need to give them internal linkage by making them 
static. 
Friends
You
can 
inject
a
friend
declaration
into a namespace by
declaring it within an enclosed class:
 
namespace me {
  class Us {
    //...
    friend you();
  };Now
the function 
you( )
is a member of the namespace 
me. 
Using
a namespace
You
can refer to a name within a namespace in
two ways: one name at a time, using the scope resolution operator, and more
expediently with the 
using
keyword. 
Scope
resolution
Any
name in a namespace can be explicitly specified using the scope resolution
operator, just like the names within a class:
 
namespace X {
  class Y {
    static int i;
  public:
    void f();
  };
  class Z;
  void func();
}
class X::Z {
  int u, v, w;
public:
  Z(int i);
  int g();
X::Z::Z(int i) { u = v = w = i; }int
X::Z::g() { return u = v = w = 0; }
 
void X::func() {
  X::Z a(1);
  a.g();So
far, namespaces look very much like classes.
 
The
using directive
Because
it can rapidly get tedious to type the full qualification for an identifier in
a namespace, the 
using
keyword allows you to import an entire namespace at once. When used in
conjunction with the 
namespace
keyword, this is called a 
using
directive.
The 
using
directive declares all the names of a namespace to be in the current scope, so
you can conveniently use the unqualified names:
 
namespace math {
  enum sign { positive, negative };
  class Integer {
    int i;
    sign s;
  public:
    Integer(int ii = 0) 
      : i(ii),
        s(i >= 0 ? positive : negative)
    {}
    sign getSign() { return s; }
    void setSign(sign sgn) { s = sgn; }
    // ...
  };
  Integer a, b, c;
  Integer divide(Integer, Integer);
  // ...Now
you can declare all the names in 
math
inside a function, but leave those names nested within the function:
 
void arithmetic() {
  using namespace math;
  Integer x;
  x.setSign(positive);Without
the 
using
directive, all the names in the namespace would need to be fully qualified.
 One
aspect of the 
using
directive may seem slightly counterintuitive at first. The visibility of the
names introduced with a 
using
directive is the scope where the directive is made. But you can override the
names from the 
using
directive as if they’ve been declared globally to that scope! 
 
void q() {
  using namespace math;
  Integer A; // Hides math::A;
  A.setSign(negative);
  math::A.setSign(positive);If
you have a second namespace:
 
namespace calculation {
  class Integer {};
  Integer divide(Integer, Integer);
  // ...And
this namespace is also introduced with a 
using
directive, you have the possibility of a collision. However, the ambiguity appears
at the point of 
use
of the name, not at the 
using
directive:
 
void s() {
  using namespace math;
  using namespace calculation;
  // Everything’s ok until:
  divide(1, 2); // AmbiguityThus
it’s possible to write 
using
directives to introduce a number of namespaces with conflicting names without
ever producing an ambiguity.
 
The
using declaration
You
can introduce names one at a time into the current scope with a 
using
declaration.
Unlike the 
using
directive, which treats names as if they were declared globally to the scope, a 
using
declaration is a declaration within the current scope. This means it can
override names from a 
using
directive:
 
namespace U {
  void f();
  void g();
}
namespace V {
  void f();
  void g();
void func() {
  using namespace U; // Using directive
  using V::f; // Using declaration
  f(); // Calls V::f();
  U::f(); // Must fully qualify to callThe
using
declaration just gives the fully specified name of the identifier, but no type
information. This means that if the namespace contains a set of overloaded
functions with the same name, the 
using
declaration declares all the functions in the overloaded set.
 You
can put a 
using
declaration anywhere a normal declaration can occur. A 
using
declaration works like a normal declaration in all ways but one: it’s
possible for a 
using
declaration to cause the overload of
a function with the same argument types (which isn’t allowed with normal
overloading). This ambiguity, however, doesn’t show up until the point of
use, rather than the point of declaration.
 A
using declaration can also appear within a namespace, and it has the same
effect as anywhere else: that name is declared within the space:
 
namespace Q {
  using U::f;
  using V::g;
  // ...
}
void m() {
  using namespace Q;
  f(); // Calls U::f();
  g(); // Calls V::g();A
using declaration is an alias, and it allows you to declare the same function
in separate namespaces. If you end up redeclaring the same function by
importing different namespaces, it’s OK – there won’t be any
ambiguities or duplications.
 
[35]
Your compiler may not have implemented this feature yet; check your local
documentation.
 
  
	
		
		  Contact: webmaster@codeguru.com
		  
		  CodeGuru - the website for developers.