Namespace in C++
Namespace is like a special container or a label that holds a group of names - like variables, functions, or classes - to avoid confusion when we have the same name used in different parts of the program.
Example
#include <iostream>
namespace Room1 {
// Function greet inside namespace Room1
void greet() {
std::cout << "Hello from Room 1!" << std::endl;
}
}
namespace Room2 {
// Function greet inside namespace Room2
void greet() {
std::cout << "Hello from Room 2!" << std::endl;
}
}
int main() {
// Use the scope resolution operator (::) to access greet() function inside namespace Room1
Room1::greet();
Room2::greet();
return 0;
}
Output
Hello from Room 1! Hello from Room 2!
Namespace with using Directive
We can also avoid prepending of namespaces with the using namespace directive. This directive tells the compiler that the subsequent code is making use of names in the specified namespace.
#include <iostream>
namespace first_space {
void func() {
std::cout << "Inside first_space"
<< std::endl;
}
}
// Using first_space
using namespace first_space;
int main() {
// Call the method of first_space
func();
return 0;
}
Output
Inside first_space
Names introduced in a using directive obey normal scope rules. The name is visible from the point of the using directive to the end of the scope in which the directive is found. Entities with the same name defined in an outer scope are hidden.
Instead of accessing the whole namespace, another option (known as using declaration) is to access a particular item within a namespace. For example, if the only part of the std namespace that you intend to use is cout, you can refer to it as follows:
#include <iostream>
namespace first_space {
void func() {
std::cout << "Inside first_space" << std::endl;
}
}
// Using first_space
using first_space::func;
int main() {
// Call the method of first_space
func();
return 0;
}
Output
Inside first_space
Nested Namespace
We can nest one namespace into another. Such namespaces are called nested namespaces.
Example:
// Outer namespace
namespace outer {
void fun(){
cout << "Inside outer namespace" << endl;
}
// Inner namespace
namespace inner {
void func() {
cout << "Inside inner namespace";
}
}
}
Accessing members in nested namespaces require multilevel scope resolution as shown:
#include <iostream>
using namespace std;
// Outer namespace
namespace outer {
void fun(){
cout << "Inside outer namespace" << endl;
}
// Inner namespace
namespace inner {
void func() {
cout << "Inside inner namespace";
}
}
}
int main() {
// Accessing member of inner
// namespace
outer::inner::func();
return 0;
}
Output
Inside inner namespace
In-built Namespaces
C++ already uses some inbuilt namespaces that we are already familiar with. Let's look at some of the common ones:
std Namespace
In C++, std namespace is the part of standard library, which contains most of the standard functions, objects, and classes like cin, cout, vector, etc. It also avoids conflicts between user-defined and library-defined functions or variables.
#include <iostream>
using namespace std;
int main() {
int a = 3, b = 7;
// 'cout' and 'endl' are part of the std namespace
cout << "Sum: " << a + b ;
return 0;
}
Output
Sum: 10
Note: ADL (Argument-Dependent Lookup) in C++ is a feature that automatically searches for functions or operators based on the types of the function's arguments.
Global Namespace
The global namespace is the default namespace where all the functions, variables, and classes that are not explicitly declared inside any namespace. Everything outside of any namespace is considered to belong to the global namespace.
We can access the global namespace using scope resolution operator(::) followed by global namespace name.
Example:
#include <bits/stdc++.h>
using namespace std;
int n = 3;
int main() {
int n = 7;
// Accessing global namespace
cout << ::n << endl;
cout << n;
return 0;
}
Output
3 7
Extending Namespace
In C++, extending a namespace means adding more features (like functions, variables, or classes) to an existing namespace, even if that namespace was defined somewhere else (like in a library or another file).
Example:
#include <bits/stdc++.h>
using namespace std;
namespace nmsp{
void func(){
cout << "You can extend me" << endl;
}
}
// Extending the same namespace
namespace nmsp{
void func2(){
cout << "Adding new feature";
}
}
int main() {
nmsp::func();
nmsp::func2();
return 0;
}
Output
You can extend me Adding new feature
Creating an Alias for Namespace
We can also create an alias of existing namespace using namespace.
namespace namespace_name{
// Members of namespace
}
// Creating a alias of namespace_name
namespace nn = namespace_name;
Inline Namespace
An inline namespace is a type of namespace where its members are accessible directly without using the namespace name.
Example:
#include <iostream>
using namespace std;
inline namespace inline_space {
void display() {
cout << "Inside inline namespace";
}
}
int main() {
// Direct access due to inline namespace
display();
return 0;
}
Output
Inside inline namespace
Anonymous Namespace
A namespace does not have a name called an anonymous namespace. It ensures that the entities in the unnamed namespace are limited to that file.
Example:
#include <iostream>
using namespace std;
// Anonymous namespace
namespace {
int value = 10;
}
int main() {
// Accessing anonymous namespace variable
cout << value;
return 0;
}
Output
10
Namespace vs Class
Namespaces and classes may look similar, but they are completely different. The differences between namespaces and classes are shown below:
Namespace | Class |
---|---|
It is used to organize code and prevent name collisions in large projects. | Used to define and create objects that encapsulate data and behavior. |
Does not encapsulate data or behavior; it only provides scope. | Encapsulates both data members and methods into objects. |
Does not have access modifiers (public, private, protected). | Has access modifiers (public, private, protected) to control the visibility of members. |
Cannot be inherited. | Can be inherited to create subclasses. |
A namespace is not instantiated; it is used to group entities. | A class is instantiated to create objects. |
Does not directly consume memory; it only provides scope for identifiers. | Consumes memory as objects are created from a class. |
Used to organize code and avoid name conflicts, especially in large projects. | Used to create objects and model real-world entities with attributes and behaviors. |
No constructors or destructors. | Has constructors and destructors to initialize and destroy objects. |