This page was last updated August, 2004


Namespaces


Consider the following problem in code in which both MyHeader.h and YourHeader.h define a structure called Node.


     // MyHeader.h 
     struct Node
     {
        int     key;
        char    data[32];
     };

     // YourHeader.h 
     struct Node
     {
        char   nodeKey;
        int    iData;
        double dData;
     };

     //  MyProgram.cpp 
     #include "MyHeader.h"
     #include "YourHeader.h"

     void main()
     {
          Node  n;
     }

This will cause a compiler error because Node is being redefined in the second header file. This becomes even more serious if I accidentally use a variable, function, or class name in my source or header files that are part of a standard header or library.


Defining Namespaces

C++ allows me to get around this by declaring the names of my variables, functions, and classes as existing in a defined namespace. I can then use the namespace name to qualify the names of my variables, functions, and classes so there is no confusion or conflict. Look at the following code sample.


// MyHeader.h
namespace MyNameSpace
{ 
     struct Node
     {
          int   key;
          char  data[32];
     };
} 

// YourHeader.h 
namespace YourNamespace
{
     struct Node
     {
          char    nodeKey[5];
          int     iData;
          double  dData;
     }
}

//  MyProgram.cpp 
#include MyHeader.h
#include YourHeader.h

void main()
{
     MyNameSpace::Node		n1;
     YourNameSpace::Node	n2;

     n1.key = 32;
     strcpy(n2.nodeKey, "ABCD");
}

Now there is no compiler error and I can keep the names separate by using then namespace names as qualifiers.

How does this work?
The compiler keeps a table of the names of all variables, functions, and classes that I use in my program. All of these are part of the Global Namespace. If I define a new namespace then the compiler creates another table for all those names.

It is also not necessary for me to put all the code that will be a part of a namespace in a single location (header or source file). Here is an example:

Implementation 1
Part of main source file
Implementation 2
Part of main source file in two places
Implementation 3
IN separate header and source files
namespace MyNS
{
   // Function prototypes
   void function1();
   void function2();
   void function3();
   // Function 1 implementation
   void function1()
   {
      cout << "MyNS::function1\n";
   }

   // Function 2 implementation
   void function1()
   {
      cout << "MyNS::function2\n";
   }

   // Function 3 implementation
   void function1()
   {
      cout << "MyNS::function3\n";
   }
} // end namespace MyNS

void main()
{
   MyNS::function1();
   MyNS::function2();
   MyNS::function3();

}
			
namespace MyNS
{
   // Function prototypes 
   void function1();
   void function2();
   void function3();
}


void main()
{
   MyNS::function1();
   MyNS::function2();
   MyNS::function3();

}

namespace MyNS
{
   // Function 1 implementation
   void function1()
   {
      cout << "MyNS::function1\n";
   }

   // Function 2 implementation
   void function1()
   {
      cout << "MyNS::function2\n";
   }

   // Function 3 implementation
   void function1()
   {
      cout << "MyNS::function3\n";
   }
} // end namespace MyNS
			
// MyNS.h
#ifndef MYNS_H
#define MYNS_H

namespace MyNS
{
   // Function prototypes 
   void function1();
   void function2();
   void function3();
}
#endif

// MyNS.cpp
namespace MyNS
{
   // Function 1 implementation
   void function1()
   {
      cout << "MyNS::function1\n";
   }

   // Function 2 implementation
   void function1()
   {
      cout << "MyNS::function2\n";
   }

   // Function 3 implementation
   void function1()
   {
      cout << "MyNS::function3\n";
   }
} // end namespace MyNS
			



Using Namespaces

In the above implementations in order to call one of the functions defined in MyNS namespace you had to use the namespace with the function call as in MyNS::function1(). If you want to use variables and functions defined in a particular namespace without having to qualify it each time you can use the using declaration or the using directive. These are two different functionalities for the same keyword.

The using declaration
With the using declaration you can specify which variable or function you want to use from a defined namespace. After that you do not have to qualify which you are referring to. Look at the following simple example:
namespace  MyNS
{
    int x = 1;    // Declare variable x in namespace MyNS
}

int x = 0;       // Declare variable x in global namespace

void main()
{
    using MyNS::x;   // Reference x variable  from namespace MyNS
    cout << x;       // Value 1 will be printed not 0

    cout << ::x;     // Explicitly reference global name space to print 0
}

Now here is a more involved example:
// File: AccessDemo.cpp

#include <iostream.h>

// Declare namespace 1 with function1()
namespace NS1
{
   void function1()	// Function implementation
   {
      cout << “NS1::function1() \n”;
   }
} // end NS1

// Declare namespace 2 with function1()
namespace NS2
{
   void function1()	// Function implementation
   {
      cout << “NS2::function1() \n”;
   }
} // end NS1

// Declare function1() in global namespace
void function1()	// Function implementation
{
   cout << “NS2::function1() \n”;
}

//-------------------------------------------------------
// main()
//-------------------------------------------------------
void main()
{
   // Explicit access demonstration
   cout << “Explicit access\n”;
   ::function1();     // Call function in global namespace
   NS1::function1();  // Call function in namespace NS1
   NS2::function1();  // Call function in namespace NS2

   // using declarationaccess
   cout << “using declaration access:\n”;
   using NS1::function1;   // Declare use of function1() from NS1
   function1();            // Call function in namespace NS1

   {   // Create a code block with an open brace
      using NS2::function1;   // Declare use of function1() from NS2
      function1();            // Call function in namespace NS2
      // This use of using only applies within this code block
   }   // End code block with a closing brace

   function1();   // Now we are outside the above code block 
                  // so the using NS2 is out of scope and the
                  // using NS1 is in scope again so call function in namespace NS1
}

With the using declaration you must specify each of the names from your namespace you want to use. To use all of the variables and functions defined in a namespace without having to qualify the names use the using directive.

The using directive
With the using directive you can specify that all of the names defined in a namespace will be used without qualifying. After that you do not have to qualify which you are referring to. Look at the following simple example:
// File: AccessDemo2.cpp
#include 

// Declare namespace 1 with function1()
namespace NS1
{
   void function1()   // Function implementation
   {
      cout << “NS1::function1() \n”;
   }
} // end NS1

// Declare namespace 2 with function1()
namespace NS2
{
   void function1()	// Function implementation
   {
      cout << “NS2::function1() \n”;
   }
} // end NS1

// Declare function1() in global namespace
void function1()	// Function implementation
{
   cout << “NS2::function1() \n”;
}

//-------------------------------------------------------
// main()
//-------------------------------------------------------
void main()
{
   // Using directive giving default access to all of NS2
   using namespace NS2;

   NS1::function1();   // Explicit call to function1() in namespace NS1
   ::function1;        // Explicit call to function1() in global namespace
   function1();        // Call function1() in namespace NS2

}
The Standard C++ namespace
C++ provides a special namespace called std that wraps the entire standard library. This includes all the standard C++ header files. These must be qualified with std::. If you use #include <iostream> (without the .h) then to use cout you must qualify it as std::cout. If you use #include you do not have to qualify it.

You can use #include <iostream>;
Then use using std::cout;
To avoid having to qualify cout every time you use it.

You can also use using namespace std; to get access to cout and all other things defined in std.