Skip to content

Latest commit

 

History

History
102 lines (77 loc) · 2.68 KB

namespace.asciidoc

File metadata and controls

102 lines (77 loc) · 2.68 KB

C++ Namespaces

Table of Contents

Problem Statement

First year students always have to been explained that it’s okay to reuse the same name for local variables in different functions or methods. Imagine if this were not the case: each time you’d have to make sure the name you chose is unique across potentially thousands of lines of code.

Fortunately, names are scoped, i.e., the scope of an identifier is the part of the code in which the identifier "lives". You can reuse the same identifier as long as their scopes don’t overlap. If there is overlap, there are certain rules that determine what the identifier refers to.

For example,

int x;

struct Foo
{
    int x;

    void foo()
    {
        int x;
    }
}

There are three variables, all bound to the same identifier x. Their scopes also overlap. Inside foo, the following rules apply:

  • x refers to the local variable.

  • To access the field, one can use this→x.

  • The global variable is reachable through ::x.

Type identifiers are more problematic though: by default, `struct`s and `class`es are all defined in the global scope, which means their scope always overlap.

Therefore, name clashes are a potential problem: you need to take care to assign a unique name to each of your types. When working in large teams or with external code (i.e., libraries), this can become a serious issue. Note that function are less likely to suffer from this problem thanks to overloading.

Solution

Enter namespaces. A namespace is similar to Java’s packages: one can define multiple classes with the same name, as long as they are in different namespaces. However, in Java, anything in a package foo must be placed in a directory named foo. No such restriction exists in C++:

  • A file can contain any namespace it wants.

  • A file can contain any number of namespaces it wants.

The syntax is as follows:

Header file
namespace my_namespace
{
    void my_function();

    struct my_type
    {
        void my_method();
    };
}
CPP file
void my_namespace::my_function() { ... }

void my_namespace::my_type::my_method() { ... }

To refer to something in a namespace, you simply prefix it with ns:: where ns is the name of the namespace. An example you already encountered is the std namespace: std::cout, std::vector<int>, etc.

#include "header-file.h"

void some_other_function()
{
    my_namespace::my_function();

    my_namespace::my_type local_variable;
    local_variable.my_method();
}