C++的語法中經過在派生類中使用using聲明能夠忽略繼承方式 , 而讓派生類對於基類的私有和保護成員具備特殊的訪問權限 , 甚至能夠改變派生類對象對於基類成員的訪問權限 .ios
我的認爲這種語法很容易讓別人對於本身的代碼產生誤解 , 應該儘可能少用或不用 . 爲防止本身忘記 , 下面記錄一下我的的理解 .函數
引用之C++ Primer5 P546spa
經過在類的內部使用using聲明語句 , 咱們能夠將該類的直接或間接基類中的任何可訪問成員標記出來 (非私有成員) . using聲明語句中名字的訪問權限由該using聲明語句以前的訪問說明符來決定code
白話文解釋 : 在派生類的內部經過using聲明語句 , 咱們能夠忽略繼承方式 ,改變派生類中可訪問的基類成員在派生類中的訪問權限 . orm
文字可能很差理解 , 看代碼實例更容易體會
對象
1 class Base 2 { 3 public: 4 int base_public; 5 protected: 6 int base_protect; 7 private: 8 int base_private; 9 }; 10 11 class Derive :private Base 12 { 13 public: 14 using Base::base_public; 15 protected: 16 using Base::base_protect; 17 private: 18 //using Base::base_private; // error , 編譯器報錯 , 不可訪問 19 };
代碼示例中 , 派生類Derive經過private的方式繼承了基類Base , 然而又經過using聲明改變了基類成員的訪問權限 ,blog
也就是說這段代碼中 , 雖然表面上派生類是以private的方式繼承了基類 ,而實際上派生類對於基類的訪問權限就是public的方式 ! 繼承
代碼實例中能夠看出在派生類中沒法經過using聲明來標記基類的私有成員 , 也驗證了書中的話 .ci
因爲繼承的特性 , 基類的私有成員仍然會自動成爲派生類的私有成員作用域
然而這樣的代碼 , 很容易讓人產生誤解 .
using聲明語句中名字的訪問權限由該using聲明語句以前的訪問說明符來決定
經過這一特性 , 甚至能夠改變基類成員在派生類中的訪問權限 ! 一樣經過一些代碼來演示
1 #pragma warning (disable:4996) 2 #include <iostream> 3 4 class Base 5 { 6 public: 7 int base_public = 1; 8 protected: 9 int base_protect = 2; 10 private: 11 int base_private = 3; 12 }; 13 14 class Derive :private Base 15 { 16 public: 17 //在public做用域聲明基類中的成員 18 using Base::base_public; 19 using Base::base_protect; 20 //using Base::base_private; // error , 編譯器報錯 , 不可訪問 21 }; 22 23 int main() 24 { 25 Derive test; 26 std::cout << "基類的公有成員: "<< test.base_public << std::endl; 27 std::cout << "基類的保護成員: " << test.base_protect << std::endl; 28 //std::cout << "基類的私有成員: " << test.base_private << std::endl; //error , 不可訪問 29 30 system("pause"); 31 return EXIT_SUCCESS; 32 }
代碼中經過給基類的成員設定了默認初始值以便訪問時顯示 , 最終的運行結果以下
基類的公有成員: 1 基類的保護成員: 2 請按任意鍵繼續. . .
代碼中派生類繼承時一樣使用private的方式繼承 , 然而咱們把using聲明放在了public權限下 , 因爲 " using聲明語句中名字的訪問權限由該using聲明語句以前的訪問說明符來決定"
因此此時基類中的公有成員和保護成員都變成了派生類中的公有成員 , 也就是說經過using聲明 , 咱們經過私有繼承的派生類 比 公有繼承的訪問權限反而更高 !
在main()函數中 派生類的對象能夠訪問基類的保護成員也驗證了基類的保護成員在派生類中的訪問權限已變成公有 .
也就是說經過這樣的方式派生類對象能夠訪問基類的保護成員 , 而基類本身的對象卻沒法訪問 .
須要注意的是經過派生類訪問基類的保護成員時 , 編譯器並不會給出智能提示 .
經過在類的內部使用using聲明語句 , 咱們能夠將該類的直接或間接基類中的任何可訪問成員標記出來 (只限於非私有成員) . using聲明語句中名字的訪問權限由該using聲明語句以前的訪問說明符來決定