C++: Namespaces

In C++, namespaces are simply named scopes of code, most commonly used to prevent naming conflicts. A lot of the standard library C++ stuff is declared in the 'std' namespace as we've previously discussed, and as such most of our applications up until this point have contained the line using namespace std; near the top of the document. This line brings the namespace into the scope where the using statement is written, and as such we usually bring everything from the 'std' namespace into a global scope so that we don't have to manually scope out each instance of cout, endl, or other things that use the std namespace using the scope resolution operator - e.g. std::cout and std::endl.

The problem is that putting a using namespace statement at the top of our different code documents somewhat defeats the point of namespaces. Everything was put inside the 'std' namespace to prevent naming conflicts with other things, but we're just telling everything to come back out into the global scope so we can use them. This isn't a brilliant idea, as can be demonstrated by something like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>

using namespace std;

struct string
{
	//Some custom stuff for our own homemade 'string' struct
};

int main()
{
	string name; //The compiler is screaming: "Which one do I use?!"

	return 0;
}

The above will not compile as the compiler simply doesn't know whether to use the "string" declared in the 'std' namespace in the "string" header file which we brought into a global scope by using namespace std;, or to use the "string" structure that we declared. Just to go off on a small tangent, if you're interested in making this example somewhat more practical and testing your knowledge of dynamic memory allocation, it might be a good idea to actually try to create your own "string" class by dynamically allocating character arrays. An example solution is as follows (it's a little messy, but it works!), it might be a good idea to read through it to see how much you can understand (we've covered it all):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>

struct string
{
    char* array;
    string() { array = NULL; }
    string(char data[], int length) { array = NULL; set(data, length); } //Constructor
    void set(char data[], int length) //Member function to set the string to a value
    {
        if(array != NULL) //If the array has been previously used
        {
            for(int i = 0; i < (sizeof(array)/sizeof(array[0])); i++) //Loop the same number of times as the current array length
            {
                array[i] = '\0'; //Nuke the array with '\0' - NULLs.
            }
            delete [] array; //Free up the memory that the array was taking up
        }
        array = new char[length]; //Create a new array with dynamic size
        for(int i = 0; i < length; i++) //Loop the same number of times as the new array length
        {
            array[i] = data[i]; //Set 'array' to 'data'
        }
    }
    ~string() //Destructor
    {
        if(array != NULL) //If the array has been previously used
            delete [] array; //Free up the memory that the array was taking up
    }
};

int main()
{
    string greeting; //New object of 'string' called 'greeting'

    greeting.set((char*)"Hello", 5); //object.array = {'H', 'e', 'l', 'l', 'o'}
    std::cout << greeting.array << std::endl;

    greeting.set((char*)"Hey", 3); //object.array = {'H', 'e', 'y'}
    std::cout << greeting.array << std::endl;

    greeting.set((char*)"What's Up?", 10); //object.array = {'W', 'h', 'a', 't', '\'', 's', ' ', 'U', 'p', '?'}
    std::cout << greeting.array << std::endl;


    return 0;
}

The problem with having to use the namespace name and scope resolution operator before things that "live" in a certain namespace is that typing things like std::cout a bunch of times can get tiring and repetitive - even if we don't want everything from the 'std' namespace brought into a more accessible scope, it's usually safe to say that we want 'cout' to relate to the 'std' namespace. As such we can use the using keyword to specifically use the 'std' namespace for certain cases by typing something like using std::cout;. This is generally better accepted than something like using namespace std; as we're specifically selecting components of the 'std' namespace which we want to bring into scope. The good thing about this method is that it explicitly specifies the parts of the namespace which we want to use in the specified scope, and as such this is often considered one of the best methods for utilizing functionality from namespaces. The following would resolve the original naming conflict which we encountered in this safe and explicit manor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>

using std::cout;
using std::endl;

struct string
{
	//Some custom stuff for our own homemade 'string' struct
};

int main()
{
	string name; //Create a new object of our 'string' struct
	//We're free to use 'cout' and 'endl' "normally" here!

	return 0;
}

In the above, an even better solution (depending on how the rest of the program is planned out) might be to put our two explicit using statements into the main function. This means that instead of std::cout and std::endl being brought into the global scope, they will be brought into the scope of main - avoiding any possible naming conflicts with our functions, classes, and other things. Similarly, the whole using namespace std; line could be moved into main if appropriate, but often this is not a good solution.

You can, of course, create namespaces of your own! This is simply done by using the namespace keyword, followed by the name of the namespace, followed by what you want the namespace to contain, in curly brackets. Namespaces can contain pretty much anything you want them to, the important part is using them to group similar things, or things with generic names. An example of some custom-made namespaces is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

namespace one
{
    double x = 3.14159;
}

namespace two
{
    int x = 21;
}

int main()
{
    using one::x; //Bring the 'x' in the namespace 'one' into this scope

    std::cout << x << std::endl; //Output 'x' (the version in 'one')
    std::cout << two::x << std::endl; //Output the 'x' in 'two'


    return 0;
}

Although the above is a rather abstract example, it should demonstrate the concept of and process of creating namespaces. We can also create aliases (other names) to namespaces if we need to - this can be done by using the equals operator on a new namespace, so something like namespace alias_name = std; would provide an alternative name to 'std' with no problems:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>

namespace my_alias = std;

int main()
{
    my_alias::cout << "Hello" << my_alias::endl;

    return 0;
}

Namespace aliasing can become particularly useful when you have nested namespaces. Take, for example, the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>

namespace one
{
    namespace two
    {
        int x = 5; //one::two::x
    }
}

namespace other_name = one::two; //Alias to one::two

int main()
{
    using std::cout; //Bring std::cout into this scope
    using std::endl; //Bring std::endl into this scope

    cout << other_name::x << endl;

    return 0;
}