|
|
|||
![]() |
Department of Engineering |
| University of Cambridge > Engineering Department > computing help > Languages > C++ |
Some simple languages only have one namespace - all function names, variable names, etc belong to the same context. Some other languages have several independent namespaces (one for variable names, one for function names, etc) making it possible to have both a variable and function with the same name, but the number and role of these namespaces are fixed.
C++ has some fixed namespaces, but it also has named namespaces and lets the user create new namespaces. It also offers control over which of these named namespaces will be used when the meaning of a symbol is required.
In order to reduce the risk of name-clashes (2 things with the same name) and errors caused by inadvertently referring to global variables, it helps to restrict the number of consulted namespaces as much as possible (as an analogy consider how "Number 44" might work ok in the context of your street, but in the context of Cambridge it's confusing). The larger the program the more useful this idea is, especially if you use libraries written by other people.
C++ has various mechanisms to control scope and visibility - for example local variables in a function and private members of an object are hidden from the outside world. The C++ namespace keyword offers a further option, so that contexts can be named and entities can be added these contexts. As we'll see later, the notation's rather like that used for classes.
Stroustrup, the author of C++, says that namespaces are a "very fundamental and relatively simple" concept, but you might find some of the later examples on the page difficult. Don't worry - as long as you can make use of the standard namespace, you should be ok.
For big programs it's probably better not to use this option.
Entities are put into a namespace by doing something like
namespace test {
int i;
int j;
}
Then test::i (the same notation that you'd use were
test an object) will access the i variable. The command
"using namespace test" will make all the entities in the
namespace available for the rest of the unit that the statement is in,
without the "test::" being necessary. Having created the test
namespace as above, you make parts of it visible as follows
void fun() {
using test::i;
// Note that in the next line the 'i' of test is used. 'j' isn't visible.
std::cout << i << std::endl;
}
int main()
{
class i {int j;};
enum letter {i, j};
letter l=i;
return 0;
}
There
are cases where the compiler gives an error message when it can't
resolve the situation. Some of the rules are rather technical, and only
come into play in artificial situations. If you pick sensible names for
things you're unlikely to encounter problems.
The following (artificial!)
program illustrates some potential
sources of conflict. Though it uses many i symbols it
compiles on our system without error. The comments show some conflicts which
would
cause trouble. It might be worth trying to compile the code with and without
the changes to see what your compiler says.
#include <iostream>
using namespace std;
namespace extra {
int i;
}
void i(){
// Compilation would fail were the next line "using extra::i"
using namespace extra;
int i; // this i masks the i in the 'extra' namespace
i=9;
cout << i << endl;
}
int main()
{
enum letter { i, j};
// Compilation would fail were the next line "class i { letter i; };"
class i { letter j; };
// Can you create an object called 'j' of type i by doing "i j;" ?
// Compilation would fail were the next line "i();"
::i();
return 0;
}
On our linux systems "g++" should work fine with the versions of the standard include files that don't have .h on the end of their names
| | On C++ namespaces by Tomas Restrepo | C++ FAQ LITE Frequently Asked Questions | C++ | Languages | computing help | |