Namespaces em C ++

Considere uma situação em que temos duas pessoas com o mesmo nome, Zara, na mesma classe. Sempre que precisamos diferenciá-los definitivamente, teríamos que usar algumas informações adicionais junto com seus nomes, como a área, se moram em área diferente ou o nome da mãe ou do pai, etc.

A mesma situação pode surgir em seus aplicativos C ++. Por exemplo, você pode estar escrevendo algum código que tem uma função chamada xyz () e há outra biblioteca disponível que também tem a mesma função xyz (). Agora, o compilador não tem como saber a qual versão da função xyz () você está se referindo em seu código.

UMA namespaceé projetado para superar esta dificuldade e é usado como informação adicional para diferenciar funções semelhantes, classes, variáveis ​​etc. com o mesmo nome disponíveis em diferentes bibliotecas. Usando o namespace, você pode definir o contexto no qual os nomes são definidos. Em essência, um namespace define um escopo.

Definindo um Namespace

Uma definição de namespace começa com a palavra-chave namespace seguido pelo nome do namespace da seguinte forma -

namespace namespace_name {
   // code declarations
}

Para chamar a versão habilitada para namespace de qualquer função ou variável, acrescente (: :) o nome do namespace da seguinte maneira -

name::code;  // code could be variable or function.

Vamos ver como o espaço de nomes escopo as entidades, incluindo variáveis ​​e funções -

#include <iostream>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// second name space
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

int main () {
   // Calls function from first name space.
   first_space::func();
   
   // Calls function from second name space.
   second_space::func(); 

   return 0;
}

Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -

Inside first_space
Inside second_space

A diretiva using

Você também pode evitar prefixar namespaces com o using namespacediretiva. Esta diretiva informa ao compilador que o código subsequente está fazendo uso de nomes no namespace especificado. O namespace é, portanto, implícito para o seguinte código -

#include <iostream>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// second name space
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

using namespace first_space;
int main () {
   // This calls function from first name space.
   func();
   
   return 0;
}

Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -

Inside first_space

A diretiva 'using' também pode ser usada para se referir a um item específico dentro de um namespace. Por exemplo, se a única parte do namespace std que você pretende usar for cout, você pode se referir a ele da seguinte maneira -

using std::cout;

O código subsequente pode referir-se a cout sem incluir o namespace, mas outros itens no std o namespace ainda precisará ser explícito da seguinte forma -

#include <iostream>
using std::cout;

int main () {
   cout << "std::endl is used with std!" << std::endl;
   
   return 0;
}

Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -

std::endl is used with std!

Nomes introduzidos em um usingas diretivas obedecem às regras normais do escopo. O nome é visível do ponto dousingaté ao fim do âmbito em que se encontra a directiva. Entidades com o mesmo nome definido em um escopo externo são ocultadas.

Namespaces descontíguos

Um namespace pode ser definido em várias partes e, portanto, um namespace é composto da soma de suas partes definidas separadamente. As partes separadas de um namespace podem ser distribuídas por vários arquivos.

Portanto, se uma parte do namespace requer um nome definido em outro arquivo, esse nome ainda deve ser declarado. Escrever uma definição de namespace a seguir define um novo namespace ou adiciona novos elementos a um existente -

namespace namespace_name {
   // code declarations
}

Namespaces aninhados

Os namespaces podem ser aninhados onde você pode definir um namespace dentro de outro namespace da seguinte maneira -

namespace namespace_name1 {
   // code declarations
   namespace namespace_name2 {
      // code declarations
   }
}

Você pode acessar membros do namespace aninhado usando operadores de resolução da seguinte maneira -

// to access members of namespace_name2
using namespace namespace_name1::namespace_name2;

// to access members of namespace:name1
using namespace namespace_name1;

Nas instruções acima, se você estiver usando namespace_name1, ele tornará os elementos de namespace_name2 disponíveis no escopo da seguinte forma -

#include <iostream>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
   
   // second name space
   namespace second_space {
      void func() {
         cout << "Inside second_space" << endl;
      }
   }
}

using namespace first_space::second_space;
int main () {
   // This calls function from second name space.
   func();
   
   return 0;
}

Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -

Inside second_space