Broad Network


Basics of C++ Namespace

C++ Namespace - Part 1

Forward: In this part of the series, I talk about the basics of C++ Namespace.

By: Chrysanthus Date Published: 7 Feb 2013

Introduction

This is part 1 of my series, C++ Namespace. In this part of the series, I talk about the basics of C++ Namespace. My volume, C++ Course (Taking the Bull by the Horns) is divided into two portions. The first portion is the professional course; the second portion is the advanced course to make you an expert. The second portion is divided further into two more portions. The first portion here deals with C++ core coding. The second portion deals with the C++ standard library and how to produce a library of your own. I hope you go through the volume, continuing from here.

Back to the story at hand: Basics of C++ Namespace. C++ namespace prevents the ambiguity on the use of names. Get the details as you read along.

Prerequisite
This series is part of my C++ Course volume. So you should have completed all the series before this one, in the volume. This series is a continuation. To know what you should have already covered, just click the link, “C++ Course” below.

A problem
Read and try the following code:

int myInt = 3;
int yourInt = 5;

int herInt = myInt + yourInt;

int main()
    {
        
        return 0;
    }

The compilation of the above code went well. The execution phase went well. Note that I did not use the cout object. In the above code, you have the initialization of two integers with two identifiers. You have one addition statement, where a third identifier is defined. The main function has only the return-zero statement. Just note that I did not use the following two lines in the (top of the) above code:

        #include <iostream>
        using namespace std;

These two lines especially the second one are related to the namespace concept. You will know their uses later.

Note, a program can never be executed unless it is compiled successfully.

Now, read and try the following code where another identifier is defined (the code will not compile and will issue error messages – note the error messages issued). The two identifiers have the same name, myInt.

int myInt;

int myInt = 3;
int yourInt = 5;

int herInt = myInt + yourInt;

int main()
    {
        
        return 0;
    }

The program (code) did not compile and error messages were issued. The reason the code did not compile is because you cannot have more than one identifier with the same name in the same scope (see details later). The scope in question here is the file scope (or global scope – details later).

Normally, if you write a one-file program you would probably be conscious not to have two identifiers with the same name in the same scope. However, the problem can arise because many programs (applications) are large and are each written by different people; each person may write a file. The files are combined with the include directives (in a header). I continue the explanation with one file, before I talk about multiple files, later.

When talking about namespaces, we are talking about identifiers, in a way that you should use them. By the word identifier I am referring to identifiers of fundamental object types, identifiers of derived object types (all sorts), identifiers of classes and identifiers of functions.

To solve the above name ambiguity (conflict) with one file or with multiple files, the inventors of C++ came up with the idea of namespaces. It is simple: you are advised to have the identifiers of your code in a block (pair of curly braces). That block is a namespace. The block has a name, which you give. That name is the identifier of the block. That identifier is the name of the namespace. For simplicity, we shall have initialization of fundamental objects and declaration of functions in the namespaces below.

The Scope Resolution Operator
The scope resolution operator is the operator, :: . It is used with namespaces. Read and try the following code (there is no output):

namespace first
    {
        int ident = 33;
        void fn();
    }

namespace second
    {
        int ident = 44;
        void fn();
    }

    int myInt = first::ident;
    int yourInt = second::ident;

    void first::fn()
     {
         //cout << myInt;
     }

    void second::fn()
     {
         //some statements
     }

int main()
    {
        first::fn();
        return 0;
    }

The above code is OK. It compiles successfully. There is no output because the cout object was not effective (preceded by //) in the code.

There are two namespaces in the above code: one is called, first and the other is called, second. Inside first, you have the initialization of the identifier, ident and the declaration of the function, fn. Inside the namespace, second, you have the initialization of the identifier, ident and the declaration of the function, fn. Note that inside the two namespaces, the object identifiers and the function declarations have the same names.

In the above code, in order to use the identifier from a namespace, you have to use the scope resolution operator. You begin with the name of the namespace, then the scope resolution operator, which is :: , then the identifier (or name of function; function name is still an identifier).

The next two statements after the namespaces above, initialize two new identifiers. The first statement uses the int identifier from the namespace, which is called, first. The second statement uses the int identifier, from the namespace, which is called, second. Note the use of the scope resolution operators in these two statements. In the namespaces, the two identifiers have the same name. Outside the namespaces, they are differentiated with the scope operator preceded by the namespace names.

Below the above two statements, you have the definition of the fn function from the namespace, first and the definition of the fn function from the namespace, second. Note the use and the position of the scope operator in these two definitions. Note the position of the return type at the beginning of each of the definitions. Note the use and position of the namespace function declaration identifier in each of the definitions. In the namespaces, the two function names are the same. Outside the namespaces, they are differentiated by the scope operator preceded by the namespace names.

In the main function, the function, fn of the namespace, first, is called. To call it you start with its namespace identifier, then the scope operator and then the function name with its parentheses. In the above code, identifiers from namespaces, for fundamental objects and for functions, have been used in a similar way. All that is one way of using identifiers from namespaces.

Note: the identifiers, myInt and yourInt do not belong to any user-defined namespace. Note also that we have not used the lines “#include <iostream>” and “using namespace std;” in the above code. Their uses will be explained later.

Each time you want an identifier from a namespace, you may find it tedious to start by typing the name of the namespace, then the scope operator and finally the identifier. The following section offers a solution.

The using Keyword
Read and try the following code:

namespace first
    {
        int identA = 33;
        int identAA = 35;
    }

namespace second
    {
        int identB = 44;
        int identBB = 46;
    }

using namespace first;
int anInt = identA;
int theInt = identAA;

using namespace second;
int ourInt = identB;
int yourInt = identBB;


int main()
    {
        int mainInt =  identA;
        return 0;
    }

The above code is OK. The syntax to use the using keyword is

    using namespace namespaceIdent;

It is a statement that ends with a semicolon. When you use a statement like this at the file (global) scope level, like in the above code, then you can use an identifier from the namespace anywhere below the using statement without the preceding name of the namespace and without the scope operator (even in blocks).

In the above code, after the statement, “using namespace first;” you can use identifiers from the namespace, first. Also, after the statement, “using namespace second;” you can use identifiers from the namespace, second. You can still use identifiers of the namespace, first, after the using statement of the namespace, second. This second approach (using) to namespace can lead to conflicts when you have the same identifier name in more than one namespace; that is a disadvantage of the second approach. It only prevents you from using the namespace name and the scope operator. If you have the same identifier name in more than one namespace, then to differentiate them outside the namespace, you have to use the namespace names and the scope operator. Now, read through the above code again.

Above, I have given you the basics of C++ namespace. There is more to C++ namespace. You get that in the next parts of the series.

Chrys

Related Links

C++ Taking the Bull by the Horns
C++ Just After the Basics
Object Oriented Programming in C++
C++ Operators
C++ Templates
Exception Handling in C++
Container Library Sequences in C++ Simplified
Associative Container in C++ Simplified
String in C++ Standard Library Simplified
Date and Time in C++ Simplified
Advanced Course
Storage Duration in C++
Scopes in C++
Function and Operator Overloading in C++
Specifiers in C++
Some Features of C++ Entities
C++ Preprocessing Directives
Writing a C++ Container
C++ Namespace
Writing a C++ Application
More Related Links
Relational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem
C++ Course
NEXT

Comments

Become the Writer's Fan
Send the Writer a Message