Namespaces
As mentioned in Chapter 1, one of the
problems encountered in the C language is that you “run out of
names” for functions and identifiers when your programs reach a certain
size. Of course, you don’t really run out of names; it does, however,
become harder to think of new ones after awhile. More importantly, when a
program reaches a certain size it’s typically broken up into pieces, each
of which is built and maintained by a different person or group. Since C
effectively has a single arena where all the identifier and function names live,
this means that all the developers must be careful not to accidentally use the
same names in situations where they can conflict. This rapidly becomes tedious,
time-wasting, and, ultimately, expensive.
Standard C++ has a mechanism to prevent
this collision: the namespace keyword. Each set of C++ definitions in a
library or program is “wrapped” in a namespace, and if some other
definition has an identical name, but is in a different namespace, then there is
no collision.
Namespaces are a convenient and helpful
tool, but their presence means that you must be aware of them before you can
write any programs. If you simply include a header file and use some functions
or objects from that header, you’ll probably get strange-sounding errors
when you try to compile the program, to the effect that the compiler cannot find
any of the declarations for the items that you just included in the header file!
After you see this message a few times you’ll become familiar with its
meaning (which is “You included the header file but all the declarations
are within a namespace and you didn’t tell the compiler that you wanted to
use the declarations in that namespace”).
There’s a keyword that allows you
to say “I want to use the declarations and/or definitions in this
namespace.” This keyword, appropriately enough, is
using. All of the Standard
C++ libraries are wrapped in a single namespace, which is
std (for
“standard”). As this book uses the standard libraries almost
exclusively, you’ll see the following
using directive in almost
every program:
using namespace std;
This means that you want to expose all
the elements from the namespace called std. After this statement, you
don’t have to worry that your particular library component is inside a
namespace, since the using directive makes that namespace available
throughout the file where the using directive was
written.
Exposing all the elements from a
namespace after someone has gone to the trouble to hide them may seem a bit
counterproductive, and in fact you should be careful about thoughtlessly doing
this (as you’ll learn later in the book). However, the using
directive exposes only those names for the current file, so it is not quite as
drastic as it first sounds. (But think twice about doing it in a header file
– that is reckless.)
There’s a relationship between
namespaces and the way header files are included. Before the modern header file
inclusion was standardized (without the trailing ‘.h’, as in
<iostream>), the typical way to include a header file was with the
‘.h’, such as <iostream.h>. At that time,
namespaces were not part of the language either. So to provide backward
compatibility with existing code, if you say
#include <iostream.h>
#include <iostream>
using namespace std;
However, in this book the standard
include format will be used (without the ‘.h’) and so the
using directive must be explicit.
For now, that’s all you need to
know about namespaces, but in Chapter 10 the subject is covered much more
thoroughly.