9. Namespaces#
Namespaces allow programmers to organize code into discrete, identifiable sections. They help avoid name clashes, especially when integrating with third-party libraries, by providing a distinct container for identifier names. We’ve already been using the standard namespace, std::
. Initially, we used using namespace std;
to bring in the entire namespace into our code for convenience, but then we migrated to either including specific objects such as cout
with using std::cout
or using the namespace identifier std::
wherever cout
was located in our code.
Namespaces are containers where identifiers (like class, variable, and function names) reside. Namespaces also create a scope for these identifiers.
To understand namespaces, we also need to understand where items are defined how that affects their scope.
Variables defined -
in functions are local variables
in classes are member variables
elsewhere are global variables
Functions defined -
in classes are member functions (methods).
elsewhere are global functions.
Namespaces add a layer of disambiguation when items have the same name, but exist in different parts of a system.
9.1. Declaring#
Use the following syntax to declare a namespace.
namespace namespace_name {
// code declarations
}
9.2. Accessing Namespace Members:#
To access members (variables, functions, classes, etc.) of a namespace, use the scope resolution operator ``::.
9.3. The using Directive:#
The `using`` directive allows you to bring the entire namespace into the current scope. Be cautious with this method as it can lead to name clashes.
using MySpace;
9.4. The using Declaration:#
To introduce specific namespace members, use the `using`` declaration.
using MySpace::myVar;
The following code demonstrates declaring a namespace, MyNamespace
, and then different ways of accessing it within main
.
1//filename: namespaces.cpp
2//complile: g++ -std=c++17 -o namespaces namespaces.cpp
3//execute: ./namespaces
4#include <iostream>
5
6namespace MySpace {
7 int myVar = 10;
8 int alterMyVar() {
9 return 2 * myVar;
10 }
11}
12
13namespace AnotherSpace {
14 int myVar = 50;
15 int alterMyVar() {
16 return 3 * myVar;
17 }
18}
19
20int main(int argc, char *argv[]) {
21 int myVar = 3;
22
23 std::cout << "main: myVar - " << myVar << "\n";
24 std::cout << "MySpace: myVar - " << MySpace::myVar << "\n";
25 std::cout << "MySpace: calling alterMyVar - " << MySpace::alterMyVar() << "\n";
26
27 {
28 using namespace AnotherSpace; // this using is limited to the scope of { }
29 std::cout << "calling alterMyVar in AnotherSpace - " << alterMyVar() << "\n";
30 std::cout << "calling alterMyVar in MySpace - " << MySpace::alterMyVar() << "\n";
31 }
32
33 using namespace MySpace;
34 std::cout << "calling alterMyVar - " << alterMyVar() << "\n";
35
36 // Note that with the same identifier, C++ uses the current scope declaration.
37 std::cout << "myVar - " << myVar << "\n";
38
39 std::cout << "calling alterMyVar in AnotherSpace - " << AnotherSpace::alterMyVar() << "\n";
40
41 return EXIT_SUCCESS;
42}
Note that we can’t use using MyNamespace::myVar;
in main
as myVar
is already declared in the current scope.