Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die using
-Deklaration erstellt einen Namen im deklarativen Bereich mit der using-Deklaration.
Syntax
using [typename] nested-name-specifier unqualified-id ;
using declarator-list ;
Parameter
nested-name-specifier Eine Sequenz von Namespace-, Klassen- oder Enumerationsnamen und Bereichsauflösungsoperatoren (::), an deren Ende ein Bereichsauflösungsoperator steht. Mithilfe eines einzelnen Bereichsauflösungsoperators kann ein Name aus dem globalen Namespace eingeführt werden. Das Schlüsselwort typename
ist optional und kann verwendet werden, um abhängige Namen aufzulösen, wenn diese in einer Klassenvorlage aus einer Basisklasse eingeführt werden.
unqualified-id Ein Ausdruck für eine nicht qualifizierte ID, bei der es sich um einen Bezeichner, einen überladenen Operatornamen, einen benutzerdefinierten Literaloperator oder Konvertierungsfunktionsnamen, einen Klassendestruktornamen oder einen Vorlagennamen und eine Argumentliste handeln kann.
deklarator-list Eine durch Trennzeichen getrennte Liste von [typename
] nested-name-specifier (geschachtelte Namensbezeichner) unqualified-id-Deklaratoren, optional gefolgt von Auslassungspunkten.
Hinweise
Eine using-Deklaration führt einen nicht qualifizierten Namen als Synonym für eine an anderer Stelle deklarierte Entität ein. Damit kann ein einzelner Name aus einem bestimmten Namespace ohne explizite Qualifizierung in dem Deklarationsbereich verwendet werden, in dem er eingeführt wird. Dies steht im Gegensatz zur using-Anweisung, mit der alle Namen in einem Namespace ohne Qualifizierung verwendet werden können. Das Schlüsselwort using
wird auch für Typaliase verwendet.
Beispiel: using
-Deklaration im class-Feld
Eine using-Deklaration kann in einer Klassendefinition verwendet werden.
// 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()
Beispiel: using
-Deklaration zum Deklarieren eines Members
Bei Verwendung zum Deklarieren eines Members muss eine using-Deklaration auf den Member einer Basisklasse verweisen.
// 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()
Beispiel: using
-Deklaration mit expliziter Qualifizierung
Auf Member, die mit einer using-Deklaration deklariert werden, kann mit expliziter Qualifizierung verwiesen werden. Das Präfix ::
verweist auf den globalen Namespace.
// 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
Beispiel: Synonyme und Aliase für eine using
-Deklaration
Wenn eine using-Deklaration erfolgt, verweist das von der Deklaration erstellte Synonym nur auf Definitionen, die zum Zeitpunkt der using-Deklaration gültig waren. Definitionen, die nach der using-Deklaration einem Namespace hinzugefügt werden, sind ungültige Synonyme.
Ein Name, der durch eine using
-Deklaration definiert wird, ist ein Alias für den ursprünglichen Namen. Er wirkt sich nicht auf den Typ, die Verknüpfung oder andere Attribute der ursprünglichen Deklaration aus.
// 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);
}
Beispiel: Lokale Deklarationen und using
-Deklarationen
In Bezug auf Funktionen in Namespaces gilt Folgendes: Wenn eine Reihe von lokalen Deklarationen und using-Deklarationen in einem deklarativen Gültigkeitsbereich für einen einzelnen Namen angegeben werden, müssen alle auf dieselbe Entität verweisen, oder sie müssen alle auf Funktionen verweisen.
// 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
}
Im Beispiel oben veranlasst die using B::i
-Anweisung, dass eine zweite int i
in der g()
-Funktion deklariert wird. Die using B::f
-Anweisung steht nicht mit der f(char)
-Funktion in Konflikt, da die Funktionsnamen, die von B::f
eingeführt werden, über verschiedene Parametertypen verfügen.
Beispiel: Lokale Funktionsdeklarationen und using
-Deklarationen
Eine lokale Funktionsdeklaration kann nicht den gleichen Namen und Typ wie eine Funktion haben, die von einer using-Deklaration eingeführt wird. Zum Beispiel:
// 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)
}
Beispiel: using
-Deklaration und Vererbung
In Bezug auf Vererbung gilt Folgendes: Wenn eine using-Deklaration einen Namen aus einer Basisklasse in den Gültigkeitsbereich einer abgeleiteten Klasse einführt, überschreiben Memberfunktionen in der abgeleiteten Klasse virtuelle Memberfunktionen in der Basisklasse, die denselben Namen und dieselben Argumenttypen aufweisen.
// 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)
Beispiel: using
-Deklaration und Zugriffssteuerung
Alle in einer using-Deklaration erwähnten Instanzen eines Namens müssen verfügbar sein. Insbesondere muss der Membername zugänglich sein, wenn eine abgeleitete Klasse eine using-Deklaration verwendet, um auf einen Member einer Basisklasse zuzugreifen. Wenn der Name der einer überladenen Memberfunktion ist, muss auf alle genannten Funktionen zugegriffen werden können.
Weitere Informationen zur Zugriffsteuerung für Member finden Sie unter Memberzugriffssteuerung.
// 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
};