|
|
c m s c 214
f a l l 2 0 0 1 |
© by Charles Lin. All rights reserved. You must receive written permission from Charles Lin to reproduce this webpage in any form.
Namespaces were introduced to the C++ language to prevent "namespace clashes". For example, suppose you wish to write to use some classes written by two software companies, and both of them produce a Math class. You want to use both of them, because each class has some useful function the other one doesn't provide.
You get ready to compile the code, and the compiler complains that there are two Math classes and won't let you use both. It seems like you're stuck.
This is one reason to use namespaces. It allows you to
"qualify" each of the Math classes with a "namespace".
Think of the namespace as a kind of brand name. So, if one
company was called "SoftwareOne", they could create a namespace
for their class, as:
namespace SoftwareOne {
class Math
{
...
};
}
and if the other software company is called "WeRSoftware", then
they could create their namespace and write it as:
namespace WeRSoftware {
class Math
{
...
};
}
Each will create their own name space, and you may be able
to create "Math" objects of each type.
int main()
{
SoftwareOne::Math x; // instance of SoftwareOne Math object
WeRSoftware::Math y; // instance of WeRSoftware Math object
}
For example, here is a class in a .h file.
#include <iostream>
#include <string>
#include <vector>
class Foo {
std::string name;
std::vector<int> scores;
public:
void addScore( int num );
void readin( std::istream &input );
void print( std::ostream &output );
};
As you can see, each class type that is part of the standard
library (string, istream, ostream, vector) is preceded by
std and two colons.
Base types, such as int and float, are not classes, and so they are NOT preceded by std::.
You can "import" a namespace with the "using" directive.
It looks like:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void Foo::readin( istream &input )
{
....
}
Put the statement using namespace std; just
after all the #include's. Admittedly, this is
the "lazy" way to do it. Stanley Lippmann, who has written
a rather authoritative book called C++ Primer, prefers explicitly
importing each class, as in:
#include <iostream>
#include <string>
#include <vector>
// import each class
using std::cout;
using std::cin;
using std::string;
void Foo::readin( istream &input )
{
....
}
The "using namespace std" directive basically says "whenever you see
a class, check to see if it's in the std namespace first". Thus,
when it sees the class, string, it checks to see if it's in the
"std" namespace. Of course, it doesn't have to be (for example,
Foo isn't in that namespace).
using namespace std;and place it after the "#include" files.
#include <iostream>instead of
#include <iostream.h>Why this change? Partly, it has to do with namespaces. Partly, it has to do with there being no standard extension (some compilers expect a .H extension or a .hpp extension) for header files. So, the standard version picked something that was common to none of the vendors.
For library files that are commonly seen in C, you usually
put a "c" in front of it. For example, instead of "stdio.h"
and "stdlib.h", you write:
#include <cstdio>
#include <cstdlib>
This convention is still not quite universally used. So, if
"cstdio" and "cstdlib" don't work, you may have to resort to
the old-fashioned "stdio.h" and "stdlib.h".
We'll use g++, but feel free to use cxx as a double-check, to make sure you are using the namespaces correctly. If we find the correct options that will cause namespaces to be handled correctly, we will inform you.