- Namespaces
- A Brief Historical Background
- Properties of Namespaces
- Interaction with Other Language Features
- Conclusions
A Brief Historical Background
In the early 1990s, when C++ was gaining popularity as a general purpose programming language, many vendors were shipping proprietary implementations of various component classes. Libraries for string manipulations, mathematical functions, and container classes were integral parts of frameworks such as MFC, STL, OWL, and others. The proliferation of reusable components caused a name-clashing problem. A class named vector, for instance, could appear both in a mathematical library and in another container library that was used at the same time. A class named string could be found in almost every framework and class library. It was impossible for the compiler and the linker to distinguish between the identical names of member functions of different classes with identical names. For example, the following function could refer to two different vector classes:
bool operator==(const vector& v1, const vector& v2);
One class might be a mathematical library, whereas the other could belong to a container library.
Name clashes are not confined to third-party software libraries. In large-scale software projects, short and elegant names for classes, functions, and constants can also cause name conflicts because the same name might be used more than once to indicate different entities by different developers. In the pre-namespace era, the only workaround was to use various affixes in identifiers' names. This practice, however, is laborious and error prone:
class string // short but dangerous { // ... }; class excelSoftCompany_string /* safer but tedious */ { //... };
Namespaces enable you to use convenient, short, and intelligible names safely. Rather than repeating the unwieldy affixes time after time, you can group your declarations in a namespace and factor out the recurring affix like this:
//file excelSoftCompany.h namespace excelSoftCompany // a namespace definition { class string {/*..*/}; class vector {/*..*/}; }
You can separate the definition from the declaration of a namespace member, as in this example:
#includeusing namespace std; namespace A { void f(); //declaration } void A::f() //in a separate file, definition { cout<<"in f"<