Share via


using (Declaración)

La declaración using introduce un nombre en la región declarativa en la que aparece la declaración using.

using [typename][::] nested-name-specifier unqualified-id 
using :: unqualified-id

Comentarios

El nombre se convierte en un sinónimo de una entidad declarada en otro lugar. Permite utilizar un nombre individual de un espacio de nombres concreto sin una calificación explícita. Esto contrasta con la directiva using, que permite utilizar sin calificación todos los nombres de un espacio de nombres. Vea using (Directiva) para obtener más información. Esta palabra clave se utiliza también para los alias de tipo.

Ejemplo

Se puede utilizar una declaración using en una definición de clase.

// using_declaration1.cpp
#include <stdio.h>
class B {
public:
   void f(char) {
      printf_s("In B::f()\n");
   }

   void g(char) {
      printf_s("In B::g()\n");
   }
};

class D : B {
public:
   using B::f;
   using B::g;
   void f(int) {
      printf_s("In D::f()\n");
      f('c');
   }

   void g(int) {
      printf_s("In D::g()\n");
      g('c');
   }
};

int main() {
   D myD;
   myD.f(1);
   myD.g('a');
}
  

Cuando se utiliza para declarar un miembro, una declaración using debe hacer referencia a un miembro de una clase base.

// using_declaration2.cpp
#include <stdio.h>

class B {
public:
   void f(char) {
      printf_s("In B::f()\n");
   }

   void g(char) {
      printf_s("In B::g()\n");
   }
};

class C {
public:
   int g();
};

class D2 : public B {
public:
   using B::f;   // ok: B is a base of D2
   // using C::g;   // error: C isn't a base of D2
};

int main() {
   D2 MyD2;
   MyD2.f('a');
}
  

Se puede hacer referencia a miembros declarados con una declaración using mediante una calificación explícita. El prefijo :: hace referencia al espacio de nombres global.

// using_declaration3.cpp
#include <stdio.h>

void f() {
   printf_s("In f\n");
}

namespace A {
   void g() {
      printf_s("In A::g\n");
   }
}

namespace X {
   using ::f;   // global f
   using A::g;   // A's g
}

void h() {
   printf_s("In h\n");
   X::f();   // calls ::f
   X::g();   // calls A::g
}

int main() {
   h();
}
  

Cuando se crea una declaración using, el sinónimo creado por la declaración solo hace referencia a las definiciones que son válidas en el lugar de la declaración using. Las definiciones que se agregan a un espacio de nombres después de la declaración using no son sinónimos válidos.

Un nombre definido por una declaración using es un alias para su nombre original. No afecta al tipo, la vinculación u otros atributos de la declaración original.

// post_declaration_namespace_additions.cpp
// compile with: /c
namespace A {
   void f(int) {}
}

using A::f;   // f is a synonym for A::f(int) only

namespace A {
   void f(char) {}
}

void f() {
   f('a');   // refers to A::f(int), even though A::f(char) exists
}

void b() {
   using A::f;   // refers to A::f(int) AND A::f(char)
   f('a');   // calls A::f(char);
}

En cuanto a las funciones de espacios de nombres, si se proporciona un conjunto de declaraciones locales y declaraciones using para un único nombre en una región declarativa, todas ellas deben hacer referencia a la misma entidad o todas ellas deben hacer referencia a funciones.

// functions_in_namespaces1.cpp
// C2874 expected
namespace B {
    int i;
    void f(int);
    void f(double);
}

void g() {
    int i;
    using B::i;   // error: i declared twice
    void f(char);
    using B::f;   // ok: each f is a function
}

En el ejemplo anterior, la instrucción using B::i hace que se declare un segundo int i en la función g(). La instrucción using B::f no entra en conflicto con la función f(char) porque los nombres de función introducidos por B::f tienen distintos tipos de parámetro.

Una declaración de función local no puede tener el mismo nombre y tipo que una función introducida mediante una declaración using. Por ejemplo:

// functions_in_namespaces2.cpp
// C2668 expected
namespace B {
    void f(int);
    void f(double);
}

namespace C {
    void f(int);
    void f(double);
    void f(char);
}

void h() {
    using B::f;          // introduces B::f(int) and B::f(double)
    using C::f;          // C::f(int), C::f(double), and C::f(char)
    f('h');              // calls C::f(char)
    f(1);                // C2668 ambiguous: B::f(int) or C::f(int)?
    void f(int);         // C2883 conflicts with B::f(int) and C::f(int)
}

Con respecto a la herencia, cuando una declaración using introduce un nombre de una clase base en el ámbito de una clase derivada, las funciones miembro de la clase derivada invalidan las funciones de miembro virtual que tienen los mismos nombres y tipos de argumento en la clase base.

// using_declaration_inheritance1.cpp
#include <stdio.h>
struct B {
   virtual void f(int) {
      printf_s("In B::f(int)\n");
   }

   virtual void f(char) {
      printf_s("In B::f(char)\n");
   }

   void g(int) {
      printf_s("In B::g\n");
   }

   void h(int);
};

struct D : B {
   using B::f;
   void f(int) {   // ok: D::f(int) overrides B::f(int)
      printf_s("In D::f(int)\n");
   }

   using B::g;
   void g(char) {   // ok: there is no B::g(char)
      printf_s("In D::g(char)\n");
   }

   using B::h;
   void h(int) {}   // Note: D::h(int) hides non-virtual B::h(int)
};

void f(D* pd) {
   pd->f(1);   // calls D::f(int)
   pd->f('a');   // calls B::f(char)
   pd->g(1);   // calls B::g(int)
   pd->g('a');   // calls D::g(char)
}

int main() {
   D * myd = new D();
   f(myd);
}
  

Todas las instancias de un nombre mencionado en una declaración using deben ser accesibles. En concreto, si una clase derivada utiliza una declaración using para tener acceso a un miembro de una clase base, el nombre de miembro debe ser accesible. Si el nombre es el de una función miembro sobrecargada, todas las funciones enumeradas deben ser accesibles.

Vea Control de acceso a miembros para obtener más información sobre la accesibilidad de los miembros.

// using_declaration_inheritance2.cpp
// C2876 expected
class A {
private:
   void f(char);
public:
   void f(int);
protected:
   void g();
};

class B : public A {
   using A::f;   // C2876: A::f(char) is inaccessible
public:
   using A::g;   // B::g is a public synonym for A::g
};

Vea también

Referencia

Espacios de nombres (C++)

Palabras clave de C++