Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De using declaratie introduceert een naam in de declaratieve regio waarin de declaratie wordt weergegeven.
Syntaxis
using [typename] nested-name-specifier unqualified-id ;
using declarator-list ;
Parameterwaarden
geneste naamaanduiding Een reeks naamruimte-, klasse- of opsommingsnamen en operatoren voor bereikomzetting (::), beëindigd door een operator voor bereikomzetting. Een operator voor één bereikomzetting kan worden gebruikt om een naam uit de globale naamruimte te introduceren. Het trefwoord typename is optioneel en kan worden gebruikt om afhankelijke namen op te lossen wanneer ze worden geïntroduceerd in een klassesjabloon vanuit een basisklasse.
niet-gekwalificeerde id Een niet-gekwalificeerde id-expressie, een id, een overbelaste operatornaam, een door de gebruiker gedefinieerde letterlijke operator of naam van de conversiefunctie, een klassedestructornaam of een sjabloonnaam en argumentlijst.
declarator-list Een door komma's gescheiden lijst met [typename] geneste naamaanduidingenvoor niet-gekwalificeerde id-declaraties , gevolgd door een beletselteken.
Opmerkingen
Een using-declaratie introduceert een niet-gekwalificeerde naam als synoniem voor een entiteit die elders is gedeclareerd. Hiermee kan één naam uit een specifieke naamruimte worden gebruikt zonder expliciete kwalificatie in de declaratieregio waarin deze wordt weergegeven. Dit is in tegenstelling tot de gebruiksrichtlijn, waardoor alle namen in een naamruimte zonder kwalificatie kunnen worden gebruikt. Het using trefwoord wordt ook gebruikt voor typealiassen.
Voorbeeld: using declaratie in klasseveld
Een using-declaratie kan worden gebruikt in een klassedefinitie.
// 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()
Voorbeeld: using declaratie om een lid te declareren
Wanneer een lid wordt gede declareerd, moet een using-declaratie verwijzen naar een lid van een basisklasse.
// 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()
Voorbeeld: using declaratie met expliciete kwalificatie
Leden die zijn gedeclareerd met behulp van een declaratie kunnen worden verwezen met behulp van expliciete kwalificatie. Het :: voorvoegsel verwijst naar de globale naamruimte.
// 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
Voorbeeld: using synoniemen en aliassen van declaratie
Wanneer een gebruiksdeclaratie wordt gemaakt, verwijst het synoniem dat is gemaakt door de declaratie alleen naar definities die geldig zijn op het punt van de gebruiksdeclaratie. Definities die zijn toegevoegd aan een naamruimte nadat de declaratie wordt gebruikt, zijn geen geldige synoniemen.
Een naam die door een using declaratie is gedefinieerd, is een alias voor de oorspronkelijke naam. Dit heeft geen invloed op het type, de koppeling of andere kenmerken van de oorspronkelijke declaratie.
// 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);
}
Voorbeeld: Lokale declaraties en using declaraties
Met betrekking tot functies in naamruimten, als een set lokale declaraties en het gebruik van declaraties voor één naam worden gegeven in een declaratieve regio, moeten ze allemaal verwijzen naar dezelfde entiteit, of ze moeten allemaal verwijzen naar functies.
// 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
}
In het bovenstaande voorbeeld zorgt de using B::i instructie ervoor dat een seconde int i in de g() functie wordt gedeclareerd. De using B::f instructie conflictt niet met de f(char) functie omdat de functienamen die zijn geïntroduceerd door B::f verschillende parametertypen hebben.
Voorbeeld: Declaraties en using declaraties van lokale functies
Een declaratie van een lokale functie mag niet dezelfde naam en hetzelfde type hebben als een functie die wordt geïntroduceerd met behulp van declaratie. Voorbeeld:
// 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)
}
Voorbeeld: using declaratie en overname
Wanneer een using-declaratie een naam van een basisklasse introduceert in een afgeleide klassebereik, overschrijft lidfuncties in de afgeleide klasse virtuele lidfuncties met dezelfde naam en argumenttypen in de basisklasse.
// 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)
Voorbeeld: using Toegankelijkheid van declaratie
Alle exemplaren van een naam die in een gebruiksdeclaratie worden genoemd, moeten toegankelijk zijn. Met name als een afgeleide klasse gebruikmaakt van een using-declaratie voor toegang tot een lid van een basisklasse, moet de lidnaam toegankelijk zijn. Als de naam van een overbelaste lidfunctie is, moeten alle benoemde functies toegankelijk zijn.
Zie Member-Access Control voor meer informatie over toegankelijkheid van leden.
// 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
};