course of C++ programming language

lecture 1: making and using objects


Namespaces

Namespaces address the problem of naming conflicts between different pieces of code. For example, you might be writing some code that has a function called foo(). One day, you decide to start using a thirdparty library, which also has a foo() function. The compiler has no way of knowing which version of foo() you are referring to within your code. You can't change the library's function name, and it would be a big pain to change your own.

Namespaces come to the rescue in such scenarios because you can define the context in which names are defined. To place code in a namespace, simply enclose it within a namespace block:

// namespaces.h namespace mycode { void foo (); }

The implementation of a method or function can also be handled in a namespace:

// namespaces.cpp #include #include "namespaces.h" namespace mycode { void foo () { std::cout << "foo() called in the mycode namespace" << std::endl; } }

By placing your version of foo() in the namespace mycode, it is isolated from the foo() function provided by the third-party library. To call the namespace-enabled version of foo(), prepend the namespace onto the function name as follows:

mycode::foo(); // Calls the "foo" function in the "mycode" namespace

Any code that falls within a mycode namespace block can call other code within the same namespace without explicitly prepending the namespace. This implicit namespace is useful in making the code more precise and readable. You can also avoid prepending of namespaces with the using directive. This directive tells the compiler that the subsequent code is making use of names in the specified namespace. The namespace is thus implied for the code that follows:

// usingnamespaces.cpp #include "namespaces.h" using namespace mycode; int main (int argc, char *argv[]) { foo(); // Implies mycode::foo(); }

A single source file can contain multiple using directives, but beware of overusing this shortcut. In the extreme case, if you declare that you're using every namespace known to humanity, you're effectively eliminating namespaces entirely! Name conflicts will again result if you are using two namespaces that contain the same names. It is also important to know in which namespace your code is operating so that you don't end up accidentally calling the wrong version of a function. You've seen the namespace syntax before - we used it in the "Hello, World!" program. cout and endl are actually names defined in the std namespace. We could have rewritten "Hello, World!" with the using directive as shown here:

// helloworld.cpp #include using namespace std; int main (int argc, char *argv[]) { cout << "Hello, World!" << endl; return 0; }

The using directive can also be used to refer to a particular item within a namespace. For example, if the only part of the std namespace that you intend to use is cout, you can refer to it as follows:

using std::cout;

Subsequent code can refer to cout without prepending the namespace, but other items in the std namespace will still need to be explicit:

// helloworld.cpp #include using namespace std::cout; int main (int argc, char *argv[]) { cout << "Hello, World!" << std::endl; return 0; }
References
  1. B.Stroustrup: The C++ programming language. Third edition.
    Section 3: a tour of the standard library; subsection 3.3: the standard library namespace; pp. 45-47.