using, deklaracja

Deklaracja using wprowadza nazwę do regionu deklaratywnego, w którym pojawia się deklaracja using.

Składnia

using [typename] nested-name-specifier unqualified-id ;
using declarator-list ;

Parametry

nested-name-specyfikr Sekwencja przestrzeni nazw, klas lub wyliczenia i operatorów rozpoznawania zakresu (::), zakończony przez operator rozpoznawania zakresu. Operator rozpoznawania pojedynczego zakresu może służyć do wprowadzenia nazwy z globalnej przestrzeni nazw. Słowo kluczowe typename jest opcjonalne i może służyć do rozpoznawania nazw zależnych w przypadku wprowadzenia do szablonu klasy z klasy bazowej.

unqualified-id Niekwalifikowane wyrażenie-identyfikatora, które może być identyfikatorem, przeciążonym operatorem, operatorem literału zdefiniowanego przez użytkownika lub nazwą funkcji konwersji, nazwą destruktora klasy lub nazwą szablonu i listą argumentów.

deklarator-lista rozdzielona przecinkami lista [typename] zagnieżdżonych specyfikatorów-name-specyfikatorówbez kwalifikacji identyfikatorów , a następnie opcjonalnie przez wielokropek.

Uwagi

Deklaracja using wprowadza niekwalifikowaną nazwę jako synonim dla jednostki zadeklarowanej gdzie indziej. Umożliwia ona używanie pojedynczej nazwy z określonej przestrzeni nazw bez wyraźnej kwalifikacji w regionie deklaracji, w którym się pojawia. Jest to w przeciwieństwie do dyrektywy using, która umożliwia używanie wszystkich nazw w przestrzeni nazw bez kwalifikacji. Słowo using kluczowe jest również używane dla aliasów typów.

Przykład: using deklaracja w polu klasy

Deklarację using można użyć w definicji klasy.

// 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;    // B::f(char) is now visible as D::f(char)
   using B::g;    // B::g(char) is now visible as D::g(char)
   void f(int) {
      printf_s("In D::f()\n");
      f('c');     // Invokes B::f(char) instead of recursing
   }

   void g(int) {
      printf_s("In D::g()\n");
      g('c');     // Invokes B::g(char) instead of recursing
   }
};

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

Przykład: using deklaracja deklarowania elementu członkowskiego

W przypadku użycia do deklarowania elementu członkowskiego deklaracja using musi odwoływać się do składowej klasy bazowej.

// 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');
}
In B::f()

Przykład: using deklaracja z jawną kwalifikacją

Członkowie zadeklarowani przy użyciu deklaracji using mogą odwoływać się przy użyciu jawnej kwalifikacji. Prefiks :: odnosi się do globalnej przestrzeni nazw.

// 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 is also visible as X::f
   using A::g;   // A's g is now visible as X::g
}

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

int main() {
   h();
}
In h
In f
In A::g

Przykład: using synonimy deklaracji i aliasy

W przypadku deklaracji using synonim utworzony przez deklarację odnosi się tylko do definicji prawidłowych w punkcie deklaracji using. Definicje dodane do przestrzeni nazw po deklaracji using nie są prawidłowymi synonimami.

Nazwa zdefiniowana przez deklarację using jest aliasem oryginalnej nazwy. Nie ma to wpływu na typ, powiązanie ani inne atrybuty oryginalnej deklaracji.

// 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);
}

Przykład: deklaracje lokalne i using deklaracje

W odniesieniu do funkcji w przestrzeniach nazw, jeśli zestaw deklaracji lokalnych i używanie deklaracji dla pojedynczej nazwy są podane w regionie deklaratywnym, wszystkie muszą odwoływać się do tej samej jednostki lub wszystkie muszą odwoływać się do funkcji.

// 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
}

W powyższym using B::i przykładzie instrukcja powoduje zadeklarowanie sekundy int i w g() funkcji . Instrukcja using B::f nie powoduje konfliktu z funkcją f(char) , ponieważ nazwy funkcji wprowadzone przez B::f program mają różne typy parametrów.

Przykład: Lokalne deklaracje funkcji i using deklaracje

Deklaracja funkcji lokalnej nie może mieć takiej samej nazwy i typu, jak funkcja wprowadzona przy użyciu deklaracji. Przykład:

// 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)
}

Przykład: using deklaracja i dziedziczenie

W odniesieniu do dziedziczenia, gdy deklaracja using wprowadza nazwę z klasy bazowej do zakresu klasy pochodnej, funkcje składowe w klasie pochodnej przesłaniają funkcje wirtualnych składowych o tej samej nazwie i typach argumentów w klasie bazowej.

// 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);
}
In D::f(int)
In B::f(char)
In B::g
In D::g(char)

Przykład: using ułatwienia dostępu deklaracji

Wszystkie wystąpienia nazwy wymienionej w deklaracji using muszą być dostępne. W szczególności jeśli klasa pochodna używa deklaracji using w celu uzyskania dostępu do składowej klasy bazowej, nazwa składowa musi być dostępna. Jeśli nazwa jest nazwą przeciążonej funkcji składowej, wszystkie funkcje o nazwie muszą być dostępne.

Aby uzyskać więcej informacji na temat ułatwień dostępu członków, zobacz Kontrola dostępu do składowych.

// 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
};

Zobacz też

Przestrzenie nazw
Słowa kluczowe