在名字空間上下文,using 一個標識符,另外一個標識符... ; 引入其它名字空間的名字到本空間。ide
using std::cout, std::endl; cout << "hello wolrd" << endl;
引入以後,本名字空間就不容許定義cout,endl這樣的有衝突的名字了:函數
using std::cout, std::endl; int cout; //編譯失敗,cout已經被佔用
在類定義的上下文,using 一個標識符,另外一個標識符...; 是把屬於基類的成員的名字引入。例如:spa
struct B { void g(char) { std::cout << "B::g(char)\n"; } void g(int ) { std::cout << "B::g(int )\n"; } }; struct D : B { using B::g; void g(int ) { std::cout << "D::g(int )\n"; } }; int main() { D d; d.g('a'); d.g(1); }
輸出:
B::g(char) D::g(int )
D類中,容許使用的名字有:B::g(char)和D::g(int).
首先:看到的是沒有名字空間上下文那樣的名字佔用和衝突問題,能夠隨意添加本身的同名標識符。
其次:派生類的同名函數,沒有徹底overhide(隱藏)基類的同名函數,其中B::g(char)沒有被隱藏掉。
所以,咱們看到在類繼承層級同名函數關係有三種:1)虛函數,由虛函數表控制的運行時多態性。子類的相同簽名的函數,override基類的函數。2)非虛函數,子類同名函數隱藏(overhide)基類的同名函數。這是很古老的規則。
如今有了3)部分的overhide,同時能部分的沿用基類的同名函數。code
還有一種using-declaration場合,構造函數的繼承(Inheriting Constructors)。blog
struct B { B(int){} }; struct D : B { using B::B; }; int main() { D d(1); }
能夠這樣想,類D,會由編譯器自動生成這樣的構造函數:繼承
struct D : B { D(int i):B(i){} };