CHAPTER 22

image

Namespaces

Namespaces are used to avoid naming conflicts by allowing entities, such as classes and functions, to be grouped under a separate scope. In the example below there are two classes that belong to the global scope. Since both classes share the same name and scope the code will not compile.

class Table {};
class Table {}; // error: class type redefinition

One way to solve this problem would be to rename one of the conflicting classes. Another solution is to group one or both of them under a different namespace by enclosing each in a namespace block. The classes then belong to different scopes and so will no longer cause a naming conflict.

namespace furniture
{
    class Table {};
}

namespace html
{
    class Table {};
}

Accessing Namespace Members

To access a member of a namespace from outside that namespace the member’s fully qualified name needs to be specified. This means that the member name has to be prefixed with the namespace it belongs to, followed by the scope resolution operator.

int main()
{
    furniture::Table fTable;
    html::Table hTable;
}

Nesting Namespaces

It is possible to nest namespaces any number of levels deep to further structure the program entities.

namespace furniture
{
    namespace wood { class Table {}; }
}

Ensure that the nested namespace members are qualified with the full namespace hierarchy when using them from another namespace.

furniture::wood::Table fTable;

Importing Namespaces

To avoid having to specify the namespace every time one of its members is used, the namespace can be imported into the global or local scope with the help of a using declaration. This declaration includes the using namespace keywords followed by the namespace to be imported. It can be placed either locally or globally. Locally, the declaration will only be in scope until the end of the code block, while at the global scope it will apply to the whole source file following its declaration.

using namespace html;    // global namespace import
int main()
{
    using namespace html; // local namespace import
}

Keep in mind that importing a namespace into the global scope defeats the main purpose of using namespaces, which is to avoid naming conflicts. Such conflicts however are mainly an issue in projects that use several independently developed code libraries.

Namespace Member Import

If you want to avoid both typing the fully qualified name and importing the whole namespace there is a third alternative available. That is to only import the specific members that are needed from the namespace. This is done by declaring one member at a time with the using keyword followed by the fully qualified namespace member to be imported.

using html::Table; // import a single namespace member

Namespace Alias

Another way to shorten the fully qualified name is to create a namespace alias. The namespace keyword is then used followed by an alias name, to which the fully qualified namespace is assigned.

namespace myAlias = furniture::wood; // namespace alias

This alias can then be used instead of the namespace qualifier that it represents.

myAlias::Table fTable;

Note that both the namespace member imports and the namespace aliases may be declared both globally and locally.

Type Alias

Aliases can also be created for types. A type alias is defined using the typedef keyword followed by the type and the alias.

typedef my::name::MyClass MyType;

The alias can then be used as a synonym for the specified type.

MyType t;

Typedef does not only work for existing types, but can also include a definition of a user-defined type – such as a class, struct, union or enum.

typedef struct { int len; } Length;
Length a, b, c;

C++11 added a using statement that provides a more intuitive syntax for aliasing types. With this syntax the keyword using is followed by the alias name and then assigned the type. Unlike typedef the using statement also allows templates to be aliased.

using MyType = my::name::MyClass;

Aliases are not commonly used since they tend to obfuscate the code. However, if used properly a type alias can simplify a long or confusing type name. Another function they provide is the ability to change the definition of a type from a single location.

Including Namespace Members

Keep in mind that in C++ merely importing a namespace does not provide access to the members included in that namespace. In order to access the namespace members the prototypes also have to be made available, for example by using the appropriate #include directives.

// Include input/output prototypes
#include <iostream>

// Import standard library namespace to global scope using namespace std;
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.171.212