C++ Namespaces


Match word(s).

If you have any questions or comments,
please visit us on the Forums.

FAQ > Explanations of... > C++ Namespaces

This item was added on: 2003/02/27

Credit: Ken Fitlike

  • Namespaces in C++ - Introduction

  • Using Namespaces In Your Own Applications

  • Nested Namespaces

  • Namespace Alias

  • Unnamed Namespaces
  • ref: Part I:8, The C++ Programming Language 3rd ed. B Stroustrup (pub:Addison-Wesley, ISBN: 0-201-88954-4)


    Namespaces in C++ - Introduction

    A namespace is a scope. Namespaces are used to make logical groupings and to avoid potential naming conflicts within C++ applications. Use of namespaces incurs no overhead to application size or performance. To use the contents of a namespace, its contents or those parts of it that are required must be brought into current scope which can be achieved in a number of different ways:

    eg. To bring an entire namespace into current scope, use the 'using' keyword, eg:

    using namespace std;

    This brings the whole of the standard template library (STL) into current scope. This is generally only used in examples; bringing the entire contents of such a namespace into current scope in this fashion defeats the purpose of namespaces. To bring a single namespace member into scope, the using keyword can be used to explicitly refer to that item, eg:

    using std::string;

    This brings the STL 'string' type into current scope. Alternatively you can simply declare your variable with full namespace syntax within code. eg:

    std::string my_string;

    This declares my_string as an object of the STL string type.


    Using Namespaces In Your Own Applications

    Since a namespace is a scope, they can be used to aggregate code with similar intent or functionality. For example, you may have a library of useful utility functions and/or classes. Grouping them together within a subjectively logical namespace and calling it 'utils' would be accomplished thus:

    
    /*
     * The header file
     */
    #if !defined HEADER_INCLUDE_GUARD 
    #define HEADER_INCLUDE_GUARD 
    
    namespace Utils
    {
      class SomethingUseful
      {
        public:
          SomethingUseful(void);
          ~SomethingUseful();
      };
    } /* end Utils namespace */
    #endif 
    
    /*
     * The source file
     */
    #include "the header file" 
    namespace Utils
    {
      SomethingUseful::SomethingUseful(void)
      {
        cout <<"Doing SomethingUseful";
      }
    
      SomethingUseful::~SomethingUseful(void)
      {
        cout <<"Doing ~SomethingUseful";
      }
    } //end Utils namespace
    
    /*
     * Alternative syntax for the source file :
     */
    
    #include "the header file" 
    Utils::SomethingUseful::SomethingUseful()
    {
      cout <<"Doing SomethingUseful";
    }
    Utils::SomethingUseful::~SomethingUseful(void)
    {
      cout <<"Doing ~SomethingUseful";
    }
    
    

    The second source file syntax clearly shows the scoping nature of namespaces while the first example involves less typing. Also some IDE's (eg. Visual C++ 6) class viewers cannot cope with the second syntax.

    Note that any namespace is open: you can have multiple files wrapped within the same namespace beyond single header/source file pairs as demonstrated above. This permits addition to the namespace at a later date, if required. The syntax remains unchanged; you can either wrap the contents of the new file(s) within:

    namespace name_of_namespace {...}

    where the ellipsis (...) represents the new member(s) added to the namespace.

    Or, for source files, you may prefer to use the alternative syntax of:

    name_of_namespace::member_name

    where name_of_namespace is the namespace name you are adding to and member_name is the name of some member class, function or variable within that namespace.


    Nested Namespaces

    Namespaces can be nested:

    
    namespace outer
    {
      namespace inner
      {
      }
    }
    
    


    Namespace Alias

    It is possible to use an alias to represent the name of another namespace. For example, in the nested namespace above, any member of 'inner' could be accessed by:

    outer::inner::member name

    Where 'member name' is the name of some member function, variable or class. Alternatively, using an alias (eg 'aoi' for 'alias-outer-inner'):

    namespace aoi = outer::inner;

    and a member of 'inner' can now be accessed with:

    aoi::member name


    Unnamed Namespaces

    For simplicity and the convenience of wrapping a set of declarations/definitions to guard against potential name clashes it is possible to omit a name for the namespace, eg:

    
    namespace 
    {
      int    a;
      char *b;
    }
    
    

    The unnamed namespace has an implicit 'using' directive so there is no problem accessing its members ie. they can be accessed as if they actually have global scope but in reality they have their names mangled by the compiler to ensure naming conflicts do not occur.

    For another explanation of namespaces, check out this tutorial on using namespaces in C++.


    Credit: Ken Fitlike

    Script provided by SmartCGIs