C++11中using關鍵字的主要做用是:爲一個模板庫定義一個別名。html
文章連接:派生類中使用using別名改變基類成員的訪問權限
ios
1、《Effective Modern C++》裏有比較完整的解釋ide
各個做用函數
/*定義別名*/ template<class T> using Tlist = std::list<T>; using Tlist = std::list<char>; Tlist listChar; //typedef void (*df)() using df = void(*)(); /*使用外部構造*/ using A::A; /*引用外部類型*/ using typename A;
2、Using 關鍵字的做用:重載父類函數
spa
1.在當前文件中引入命名空間.net
這是咱們最熟悉的用法,例如:using namespace std;htm
2.在子類中使用 using 聲明引入基類成員名稱(參見C++ primer)blog
在private或者protected繼承時,基類成員的訪問級別在派生類中更受限:繼承
class Base { public: std::size_t size() const { return n; } protected: std::size_t n; }; class Derived : private Base { . . . };
在這一繼承層次中,成員函數 size 在 Base 中爲 public,但在 Derived 中爲 private。爲了使 size 在 Derived 中成爲 public,能夠在 Derived 的 public
部分增長一個 using 聲明。以下這樣改變 Derived 的定義,可使 size 成員可以被用戶訪問,並使 n 可以被 Derived的派生類訪問:ci
class Derived : private Base { public: using Base::size; protected: using Base::n; // ... };
另外,當子類中的成員函數和基類同名時,子類中重定義的成員函數將隱藏基類中的版本,即便函數原型不一樣也是如此(隱藏條件見下面)。
若是基類中成員函數有多個重載版本,派生類能夠重定義所繼承的 0 個或多個版本,可是經過派生類型只能訪問派生類中重定義的那些版本,因此若是派生類想經過自身類型使用全部的重載版本,則派生類必須要麼重定義全部重載版本,要麼一個也不重定義。有時類須要僅僅重定義一個重載集中某些版本的行爲,而且想要繼承其餘版本的含義,在這種狀況下,爲了重定義須要特化的某個版本而不得不重定義每個基類版本,可能會使人厭煩。能夠在派生類中爲重載成員名稱提供 using 聲明(爲基類成員函數名稱而做的 using 聲明將該函數的全部重載實例加到派生類的做用域),使派生類不用重定義所繼承的每個基類版本。一個 using 聲明只能指定一個名字,不能指定形參表,使用using聲明將名字加入做用域以後,派生類只須要重定義本類型確實必須定義的那些函數,對其餘版本可使用繼承的定義。
「隱藏」是指派生類的函數屏蔽了與其同名的基類函數,規則以下:
1、若是派生類的函數與基類的函數同名,可是參數不一樣。此時,不論有無virtual關鍵字,基類的函數將被隱藏(注意別與重載混淆)
2、若是派生類的函數與基類的函數同名,而且參數也相同,可是基類函數沒有virtual關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)
#include "StdAfx.h" #include <iostream> using namespace std; class Base { public: void menfcn() { cout<<"Base function"<<endl; } void menfcn(int n) { cout<< cout<<"Base function with int"<<endl; } }; class Derived : Base { public: using Base::menfcn;//using聲明只能指定一個名字,不能帶形參表 int menfcn(int) { cout<< cout<<"Derived function with int"<<endl; } }; int main() { Base b; Derived d; b.menfcn(); d.menfcn();//若是去掉Derived類中的using聲明,會出現錯誤:error C2660: 'Derived::menfcn' : function does not take 0 arguments std::cin.ignore(std::cin.gcount()+1);//清空緩衝區 std::cin.get();//暫停程序執行 }
3、須要注意的狀況
class base{ public: void test(){ cout << "base::test()" << endl; } void test(int){ cout << "base::test(int)" << endl; } }; class derived : public base{ public: void test(){ cout << "derived::test()" << endl; } };
class derived : public base{ public: void test(){ cout << "derived::test()" << endl; } using base::test;//此聲明放在test前面和後面效果都同樣 };
class base{ public: virtual void test(){ cout << "base::test()" << endl; } virtual void test(double){ cout << "base::test(double)" << endl; } void test(int){ cout << "base::test(int)" << endl; } }; class derived : public base{ public: void test(){ cout << "derived::test()" << endl; } };
class derived : public base{ public: void test(){ cout << "derived::test()" << endl; } using base::test;//此聲明放在test前面和後面效果都同樣 };
class base{ public: virtual void test(){ cout << "base::test()" << endl; } virtual void test(double){ cout << "base::test(double)" << endl; } void test(int){ cout << "base::test(int)" << endl; } }; class derived : public base{ public: void test(){ cout << "derived::test()" << endl; } //using base::test; }; class A : public derived{ public: void test(double){ cout << "A::test(double)" << endl; } }; int main(int argc, char **argv){ base *pb = new A; pb->test(2.4); return 0; }