Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Lenguaje C

Dominando los Espacios de Nombres en C++: Evita Conflictos de Funciones

Considera una situación en la que tenemos dos personas con el mismo nombre, Zara, en la misma clase. Cada vez que necesitemos diferenciarlas, definitivamente tendremos que usar información adicional junto con su nombre, como el área si viven en diferentes áreas o el nombre de su madre o padre, etc.

La misma situación puede surgir en tus aplicaciones C++. Por ejemplo, podrías estar escribiendo algún código que tiene una función llamada xyz() y hay otra biblioteca disponible que también tiene la misma función xyz(). Ahora el compilador no tiene forma de saber qué versión de la función xyz() te estás refiriendo dentro de tu código.

Un espacio de nombres (namespace) está diseñado para superar esta dificultad y se usa como información adicional para diferenciar funciones, clases, variables, etc. similares con el mismo nombre disponibles en diferentes bibliotecas. Usando namespace, puedes definir el contexto en el que los nombres son definidos. En esencia, un namespace define un alcance.

Definiendo un Namespace

Una definición de namespace comienza con la palabra clave namespace seguida por el nombre del namespace de la siguiente manera:

namespace nombre_namespace {
    // declaraciones de código
}

Para llamar a la versión habilitada para namespace de una función o variable, antepón (::) el nombre del namespace de la siguiente manera:

nombre::código; // código podría ser variable o función.

Veamos cómo el alcance del namespace abarca las entidades incluyendo variables y funciones:

#include <iostream>
using namespace std;
// primer espacio de nombres
namespace primer_espacio {
    void func() {
        cout << "Dentro de primer_espacio" << endl;
    }
}
// segundo espacio de nombres
namespace segundo_espacio {
    void func() {
        cout << "Dentro de segundo_espacio" << endl;
    }
}
int main() {
    // Llama función del primer espacio de nombres.
    primer_espacio::func();
    // Llama función del segundo espacio de nombres.
    segundo_espacio::func();
    return 0;
}

Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:

Dentro de primer_espacio
Dentro de segundo_espacio

La Directiva using

También puedes evitar el anteponer de namespaces con la directiva using namespace. Esta directiva le dice al compilador que el código subsecuente está haciendo uso de nombres en el namespace especificado. El namespace queda así implícito para el código siguiente:

#include <iostream>
using namespace std;
// primer espacio de nombres
namespace primer_espacio {
    void func() {
        cout << "Dentro de primer_espacio" << endl;
    }
}
// segundo espacio de nombres
namespace segundo_espacio {
    void func() {
        cout << "Dentro de segundo_espacio" << endl;
    }
}
using namespace primer_espacio;
int main() {
    // Esto llama función del primer espacio de nombres.
    func();
    return 0;
}

Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:

Dentro de primer_espacio

La directiva 'using' también puede usarse para referirse a un elemento particular dentro de un namespace. Por ejemplo, si la única parte del namespace std que pretendes usar es cout, puedes referirte a él de la siguiente manera:

using std::cout;

El código subsecuente puede referirse a cout sin anteponer el namespace, pero otros elementos en el namespace std aún necesitarán ser explícitos como se muestra a continuación:

#include <iostream>
using std::cout;
int main() {
    cout << "std::endl se usa con std!" << std::endl;
    return 0;
}

Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:

std::endl se usa con std!

Los nombres introducidos en una directiva using obedecen reglas normales de alcance. El nombre es visible desde el punto de la directiva using hasta el final del alcance en el que se encuentra la directiva. Las entidades con el mismo nombre definidas en un alcance externo son ocultadas.

Namespaces Discontinuos

Un namespace puede ser definido en varias partes y así un namespace está compuesto por la suma de sus partes definidas por separado. Las partes separadas de un namespace pueden extenderse sobre múltiples archivos.

Así, si una parte del namespace requiere un nombre definido en otro archivo, ese nombre debe ser declarado. Escribir una definición de namespace siguiente ya sea define un nuevo namespace o agrega nuevos elementos a uno existente:

namespace nombre_namespace {
    // declaraciones de código
}

Namespaces Anidados

Los namespaces pueden ser anidados donde puedes definir un namespace dentro de otro namespace de la siguiente manera:

namespace nombre_namespace1 {
    // declaraciones de código
    namespace nombre_namespace2 {
        // declaraciones de código
    }
}

Puedes acceder a miembros de namespace anidado usando operadores de resolución de la siguiente manera:

// para acceder a miembros de nombre_namespace2
using namespace nombre_namespace1::nombre_namespace2;
// para acceder a miembros de nombre_namespace1
using namespace nombre_namespace1;

En las declaraciones anteriores, si estás usando nombre_namespace1, entonces hará que los elementos de nombre_namespace2 estén disponibles en el alcance de la siguiente manera:

#include <iostream>
using namespace std;
// primer espacio de nombres
namespace primer_espacio {
    void func() {
        cout << "Dentro de primer_espacio" << endl;
    }
    // segundo espacio de nombres
    namespace segundo_espacio {
        void func() {
            cout << "Dentro de segundo_espacio" << endl;
        }
    }
}
using namespace primer_espacio::segundo_espacio;
int main() {
    // Esto llama función del segundo espacio de nombres.
    func();
    return 0;
}

Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:

Dentro de segundo_espacio

Lenguaje C

  1. Dominando los Operadores en C++: Guía Completa con Ejemplos Prácticos
  2. Comentarios en C++: Mejores Prácticas para Código Legible y Mantenible
  3. Dominando las plantillas de clase en C++: guía práctica
  4. Lenguaje de Programación C++: Visión General y Características Clave
  5. Constantes y Literales en C++: Tipos, Sintaxis y Mejores Prácticas
  6. Guía Completa de Operadores en C++: Tipos, Uso y Mejores Prácticas
  7. Dominando los Tipos Numéricos en C++: Guía Práctica
  8. Entendiendo las Referencias en C++: Conceptos Clave y Diferencias con Punteros
  9. Dominando los Espacios de Nombres en C++: Evita Conflictos de Funciones
  10. Dominando Plantillas en C++: Guía de Programación Genérica
  11. Preprocesador de C++: Cómo las Directivas Moldean tu Código