A Complete Overview Of Namespaces In C++ With Simple Examples.
So far in our previous tutorials, we have seen everything about variables, declarations, functions, and other such entities used in C++.
While developing applications in C++ some peculiar situations may arise like same variable names being used twice or functions defined with same prototypes etc. When these scenarios arise, it becomes difficult for the compiler to deduce the correct variable or function call that is giving rise to ambiguity.
=> Check Out The Perfect C++ Training Guide Here.
Table of Contents:
What Is Namespace?
Let see the below Example:
#include <iostream> #include <string> int main() { int var; double var; std::cin>>var; }
Output:
In function ‘int main()’:
8:10: error: conflicting declaration ‘double var’
7:7: note: previous declaration as ‘int var’
In the above example, we have defined two variables with different types but the same identifier. So when we compile this example, we get an error as shown in the Output window. These conflicting declarations arise because of the same identifier being used to name two variables.
This type of situations gives rise to ambiguity in applications.
C++ introduces something called “namespaces” to resolve this problem. The namespace in C++ is just like a package or a region or a library which is used to differentiate between the variable or functions with the same identifiers.
A namespace can contain variables, functions, classes or other objects and even another namespace. Each member of the namespace can be referred to using a namespace space. This helps the compiler to differentiate between various programming entities even if they have the same names.
Defining A Namespace
In C++, we can define a namespace using the keyword “namespace” as shown below:
namespace namespace_name{ namespace_declarations; }
So if we need to define a namespace named “test_space”, we can do it as below:
namespace test_space{ int var=10; }
The above declaration defines a namespace named “test_space”. As shown it has an integer variable var as its the member.
Accessing Namespace Members
Now, we have defined our own namespace “test_space” and how do we access the contents of this namespace?
In C++ program, we can access the members of the namespace using the syntax:
namespace_name::namespace_member;
Thus the integer variable var declared in the namespace “test_space” above can be accessed as follows:
test_space::var;
See the complete Example below to demonstrate namespaces and its usage.
#include <iostream> #include <string> namespace test_space{ int var = 10; } int main() { double var = 20.53; std::cout<<"local var = "<<var<<std::endl; std::cout<<"test_space::var = "<<test_space::var; return 0; }
Output:
local var = 20.53
test_space::var = 10
We have demonstrated all about creating and accessing namespace in the above programming example. As we see, “test_space” is a namespace that we have defined. It has a single integer variable var defined in it. Then in the main function, we have another double variable var that is initialized.
Later we display both these variables. Note that while the local double variable inside the main can be printed directly, to print the namespace variable, we have to precede it with the namespace name.
This has also taken care of the problem of clashes among the variables because of the same names that we discussed earlier.
The Using Directive
In our previous topic, we saw that we can access namespace members using namespace_name::namespace_member.
If we do not want to specify a namespace name everywhere in the program, we can make use of the “using” directive to include the namespace in the program.
This is done as follows:
#include <iostream> #include <string> namespace test_space{ int var = 10; } using namespace std; using namespace test_space; int main() { double var = 20.53; cout<<"local var = "<<var<<endl; cout<<"test_space::var = "<<::var; return 0; }
Output:
local var = 20.53
test_space::var = 10
In the above example, we have used two statements after defining the namespace “test_space”.
These are:
using namespace std; using namespace test_space;
The first statement uses the declaration to access namespace “std” which is a predefined standard namespace in the C++ library. This namespace is used to access various functions like cin, cout, etc.
The second statement is used to include “test_space” namespace in the program.
In the main function, we can see that the functions like cout and variable var need not be preceded by a namespace name. We can directly refer to them. But as var has a name clash with a local variable in the main function, we refer it using the scope resolution operator (::) as namespaces also always have a global scope.
Nested Namespaces
C++ also allows having nested namespaces i.e. a namespace defined inside another namespace.
The general syntax of nested namespaces is as follows:
namespace ns1{ ns1_code; namespace ns2{ ns2_code; } }
If we need to access ns2_code, then we can access it as follows:
ns1::ns2::ns2_code;
Let us demonstrate the Nested Namespaces using the following code Example.
#include <iostream> #include <string> namespace first{ int var = 10; namespace second{ int secVar = 20; } } using namespace std; using namespace first; using namespace first::second; int main() { double var = 20.53; cout<<"local var = "<<var<<endl; cout<<"first::var = "<<::var<<endl; cout<<"second::var = "<<secVar; return 0; }
Output:
local var = 20.53
first::var = 10
second::var = 20
We have used nested namespaces in the above program. Please note the way in which using directive is used to access namespaces. It is not enough to refer only the innermost namespace once. If we need a code from outermost namespace then we need to refer it separately.
We can use another name for namespaces known as an “alias”. This is especially useful while using nested namespaces and the degree of nesting is high.
We can demonstrate the alias for a namespace by modifying the above Example.
#include <iostream> #include <string> namespace first{ int var = 10; namespace second{ int secVar = 20; } } using namespace std; using namespace first; namespace nested = first::second; int main() { double var = 20.53; cout<<"local var = "<<var<<endl; cout<<"first::var = "<<::var<<endl; cout<<"second::var = "<<nested::secVar; return 0; }
Output:
local var = 20.53
first::var = 10
second::var = 20
Note the alias nested that is defined for the namespace first::second. Once an alias is defined, we can then refer to the namespace using an alias name.
External Namespaces
Sometimes when we have too many namespaces to use in our application, we might want to place all the namespaces in a separate file. This can be easily done. When the namespaces are in the separate file we just include that file in our program and then directly use the namespaces and its contents in our program.
For Example, if we have a file named ns.h that contains the following namespace.
//ns.h namespace first{ int var = 25; }
Now in our program, we can use the namespace “first” as follows:
#include<iostream> #include “ns.h” using namespace std; int main() { cout<<first::var; }
So once we include the file containing namespaces in our program, we can use the namespaces as if it were declared globally in the same program.
Contiguous Namespaces
C++ also allows us to define something called as contiguous namespaces. Contiguous namespaces are the namespaces that are defined more than once by having the same name. In reality, these are not separate namespaces but the extensions of the same namespace.
Contiguous namespaces are evident in the below Example.
#include <iostream> #include <string>. namespace first{ int var = 10; } namespace first{ namespace second{ int secVar = 20; } } using namespace std; using namespace first; namespace nested = first::second; int main() { double var = 20.53; cout<<"local var = "<<var<<endl; cout<<"first::var = "<<::var<<endl; cout<<"second::var = "<<nested::secVar; return 0; }
Output:
local var = 20.53
first::var = 10
second::var = 20
Notice in the above example that we have defined the same namespace twice. In the first definition, we have a variable named var. While in the second declaration we have another namespace defined.
In the main function, we have accessed the members of the outer as well as the inner namespace and note that the members are easily accessed.
This is the example of contiguous namespaces, which is also known as “discontinuous namespaces” sometimes. Their definitions appear separate but in reality, they are continuous namespaces.
Conclusion
With this, we have come to the end of this tutorial on namespaces in C++. Namespaces in one way that allows us to separate out our code in different spaces or regions so that we have clarity in reading it and also in using its members.
In our subsequent tutorials, we will learn more about the various basic topics of C++ like exception handling, file input/output, etc.
=> Check Here To See A-Z Of C++ Training Tutorials Here.