using 宣告
using
宣告會將名稱引入宣告式區域中,其中會出現 using 宣告。
語法
using [typename] nested-name-specifier unqualified-id ;
using declarator-list ;
參數
nested-name-specifier 命名空間、類別或列舉名稱和範圍解析運算子 (::) 的序列,由範圍解析運算子終止。 可使用單一範圍解析運算子,從全域命名空間引入名稱。 關鍵字 typename
是選填的,且在從基底類別引入類別範本時可用來解析相依名稱。
unqualified-id 非限定識別碼運算式,可以是識別碼、多載運算子名稱、使用者定義常值運算子或轉換函式名稱、類別解構函式名稱或範本名稱和引數清單。
declarator-list 以逗號分隔的 [typename
] nested-name-specifier unqualified-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
宣告
就命名空間中的函式而言,如果在宣告式區域中指定一組本機宣告和使用單一名稱的宣告,則其必須全都參考相同的實體,或者其必須全都參考函式。
// 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
宣告
本機函式宣告不能與 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 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應