using 声明
using
声明将名称引入声明性区域,在该区域中显示 using 声明。
语法
using [typename] nested-name-specifier unqualified-id ;
using declarator-list ;
参数
nested-name-specifier 命名空间、类或枚举名称和范围解析运算符 (::) 的序列,由范围解析运算符终止。 单个范围解析运算符可用于从全局命名空间引入名称。 关键字 typename
是可选的,在从基类引入到类模板时,可用于解析依赖名称。
unqualified-id 非限定 ID 表达式,可以是标识符、重载运算符名称、用户定义的文本运算符或转换函数名称、类析构函数名称或模板名称和参数列表。
declarator-list [typename
] nested-name-specifierunqualified-id 声明符的逗号分隔列表,后跟省略号(可选)。
备注
using 声明引入非限定名称作为在其他地方声明的实体的同义词。 它允许使用特定命名空间中的单个名称,而无需在其显示的声明区域中显式限定。 这与 using 指令相反,该指令允许命名空间中的所有名称在没有限定的情况下使用。 using
关键字还用于类型别名。
示例:类字段中的 using
声明
可以在类定义中使用 using 声明。
// 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()
示例:用于声明成员的 using
声明
用于声明成员时,using 声明必须引用基类的成员。
// 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()
示例:具有显式限定的 using
声明
通过使用 using 声明所声明的成员可以通过使用显式限定来引用。 ::
前缀引用全局命名空间。
// 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
示例:using
声明同义词和别名
进行 using 声明时,由该声明创建的同义词仅引用在进行 using 声明时有效的定义。 using 声明后添加到命名空间的定义不是有效同义词。
using
声明定义的名称是其原始名称的别名。 它不会影响原始声明的类型、链接或其他属性。
// 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);
}
示例:局部声明和 using
声明
对于命名空间中的函数,如果在声明性区域中给出了单个名称的一组局部声明和 using 声明,则它们必须全部引用同一实体,或者必须全部引用函数。
// 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
}
在上面的示例中,using B::i
语句会导致在 g()
函数中声明第二个 int i
。 using B::f
语句与 f(char)
函数不冲突,因为 B::f
引入的函数名称具有不同的参数类型。
示例:局部函数声明和 using
声明
局部函数声明不能与使用声明引入的函数具有相同的名称和类型。 例如:
// 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)
}
示例:using
声明和继承
对于继承,当 using 声明将基类中的名称引入到派生类范围时,派生类中的成员函数将重写基类中具有相同名称和参数类型的虚拟成员函数。
// 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)
示例:using
声明可访问性
using 声明中提及的名称的所有实例都必须可访问。 具体而言,如果派生类使用 using 声明访问基类的成员,则成员名称必须可访问。 如果名称是重载成员函数的名称,则命名的所有函数都必须可访问。
有关成员可访问性的详细信息,请参阅成员访问控制。
// 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
};
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈