关于C++中公有继承、私有继承、保护继承的讨论
一、文章來由
簡單明了的理由,老生常談但是沒真正解決的問題,想搞清楚這個問題。
二、冗長的定義
我們先來看看這些冗長的定義:
公有繼承:
當類的繼承方式為公有繼承時,基類的公有成員和保護成員的訪問屬性在派生類中不變,而基類的私有成員不可直接訪問。也就是說基類的公有成員和保護成員被繼承到派生類中訪問屬性不變,仍作為派生類的公有成員和保護成員,派生類的其他成員可以直接訪問它們。在類族之外只能通過派生類的對象訪問從基類繼承的公有成員。
私有繼承:
當類的繼承方式為私有繼承時,基類中的公有成員和保護成員都以私有成員的身份出現在派生類中,而基類的私有成員在派生類中不可直接訪問。也就是說基類的公有成員和保護成員被繼承后作為派生類的私有成員,派生類的其他成員可以直接訪問它們,但是在類族外部通過派生類的對象無法直接訪問它們。無論是派生類的 成員還是通過派生類的對象,都無法直接訪問從基類繼承的私有成員。
保護繼承:
保護繼承中,基類的公有成員和保護成員都以保護成員的身份出現在派生類中,而基類的私有成員變量不可直接訪問。這樣,派生類的其他成員就可以直接訪問從基類繼承來的公有和保護成員,但在類的外部通過派生類的對象無法直接訪問它們,無論是派生類的成員還是派生類的對象都無法直接訪問基類的私有成員。
三、歸納上面冗長的定義
看完冗長的定義了,其實并沒有什么太大作用~~因為定義是獨立而嚴謹的,本來有共性的東西,沒有得到歸納和牽起聯系
好,我們來做如下歸納:
公有繼承:
1、四個字:保持原狀
2、權限:
(1)派生類成員只能訪問基類中的 public/protected 成員;
(2)派生類的對象只能訪問基類中的public成員。(注意:派生類和派生類對象是不同的)
私有繼承:
1、還是四個字:均變私有
2、權限:
(1)派生類成員也只能訪問基類中的 public/protected 成員;
(2)派生類的對象不能訪問基類中的任何的成員。
保護繼承:
1、這次字多一點:公有、保護變保護
2、權限:
(1)派生類的成員只能訪問基類中的 public/protected 成員;
(2)派生類的對象不能訪問基類中的任何的成員。
共性:
1、私有最終都是私有,且不可訪問的;
2、這就像一個權限大小包含、約束關系,仔細體會;
3、對象只有公有繼承,可以訪問 public 成員,其余的都是不能訪問的;
4、三種繼承,成員訪問都是一樣的,因為相當于基類成員被已相應的權限規則被copy到子類;
5、上面說的成員可以是:
(1)成員函數
(2)成員變量
發現還是有些太多吧,畫張圖就更明白了~~
//公有繼承【不變】 成員訪問 對象訪問 public --> public Y Y protected --> protected Y N private --> private N N//私有繼承 成員訪問 對象訪問 public --> private Y N protected --> private Y N private --> private N N//保護繼承 成員訪問 對象訪問 public --> protected Y N protected --> protected Y N private --> private N N四、例子
什么東西最后都是要用實例說話的。
例1(針對成員函數):
下面是一道軟件設計師考試題:
已知3個類O、P、Q,類O中定義了一個私有方法 F1、一個公有方法 F2 和一個保護的方法 F3;類P和類Q是類O的派生類,其繼承方式如下所示:
(1)class P: protected O{…}
(2)class Q: public O{…}
關于方法F1的描述正確的是(B):
A、方法 F1 無法被訪問
B、只有在 類O 內才能訪問方法 F1
C、只有在 類P 內才能訪問方法 F1
D、只有在 類Q 內才能訪問方法 F1
關于方法 F2 的描述正確的是(A):【這題網上答案有是C的,個人覺得錯了】
A、類 O、P、Q 的對象都可以訪問方法 F2
B、類 P 和 Q 的對象都可以訪問方法 F2
C、類 O 和 Q 的對象都可以訪問方法 F2
D、只有在 類P 內才能訪問方法 F2
關于方法 F3 的描述正確的是(B):
A、類O、P、Q的對象都可以訪問方法 F3
B、類O、P、Q的對象都不可以訪問方法 F3 【可以毫不猶豫選出】
C、類O和Q的對象都可以訪問方法F3
D、類P和Q的對象都可以訪問方法F3
然后根據上面的信息,編寫如下代碼:
/* * * funtion: 注意,如下被注釋的代碼,都是訪問不到的 * * Date:2015-7-29 * * Author: Bill Wang */#include<iostream> using namespace std;//在類O中分別定義了三個不同訪問類型的函數 class O{ public:void F2(){cout<<"this is O's public function F2"<<endl;} private:void F1(); protected:void F3(); };//類P保護繼承于O class P:protected O{ public:/*void test_F1(){F1();}*/void test_F2(){F2();}void test_F3(){F3();} };//類Q公有繼承于O class Q:public O{ public:/*void test_F1(){F1();}*/void test_F2(){F2();}void test_F3(){F3();} };//類R私有繼承于O class R:private O{ public:/*void test_F1(){F1();}*/void test_F2(){F2();}void test_F3(){F3();} };//定義在類體內或體外都一樣 void O::F1() {cout<<"this is O's private function F1"<<endl; } void O::F3() {cout<<"this is O's protected function F3"<<endl; }//主函數 int main() {O o;P p; //保護繼承Q q; //公有繼承R r; //私有繼承cout<<"O:"<<endl;//o.F1(); //私有方法o.F2(); //公有方法//o.F3(); //保護方法cout<<endl;//三種繼承:成員訪問情況一樣cout<<"P:"<<endl; // p.test_F1(); //私有方法訪問不到p.test_F2();p.test_F3();//p.F1();//p.F2();//p.F3();cout<<endl;cout<<"Q:"<<endl; // q.test_F1();q.test_F2();q.test_F3();//q.F1();q.F2();//q.F3();cout<<endl;cout<<"R:"<<endl; // r.test_F1();r.test_F2();r.test_F3();//r.F1();//r.F2();//r.F3();return 0; }運行結果如下:
完全印證了上面的題目和圖表~~
例2(針對成員變量):
是一樣的,詳見代碼
#include<iostream> using namespace std;class A //父類 { private:int privatedateA; protected:int protecteddateA; public:int publicdateA; };class B :public A //公有繼承 { public:void funct(){int b;//b=privatedateA; //error:基類中私有成員在派生類中是不可見的b=protecteddateA; //ok:基類的保護成員在派生類中為保護成員b=publicdateA; //ok:基類的公共成員在派生類中為公共成員} };class C :private A //基類A的派生類C(私有繼承) { public:void funct(){int c;//c=privatedateA; //error:基類中私有成員在派生類中是不可見的c=protecteddateA; //ok:基類的保護成員在派生類中為私有成員c=publicdateA; //ok:基類的公共成員在派生類中為私有成員} };class D :protected A //基類A的派生類D(保護繼承) { public:void funct(){int d;//d=privatedateA; //error:基類中私有成員在派生類中是不可見的d=protecteddateA; //ok:基類的保護成員在派生類中為保護成員d=publicdateA; //ok:基類的公共成員在派生類中為保護成員} };int main() {int a; B objB;//a=objB.privatedateA; //error:基類中私有成員在派生類中是不可見的,對對象不可見//a=objB.protecteddateA; //error:基類的保護成員在派生類中為保護成員,對對象不可見a=objB.publicdateA; //ok:基類的公共成員在派生類中為公共成員,對對象可見C objC;//a=objC.privatedateA; //error:基類中私有成員在派生類中是不可見的,對對象不可見//a=objC.protecteddateA; //error:基類的保護成員在派生類中為私有成員,對對象不可見//a=objC.publicdateA; //error:基類的公共成員在派生類中為私有成員,對對象不可見D objD;//a=objD.privatedateA; //error:基類中私有成員在派生類中是不可見的,對對象不可見//a=objD.protecteddateA; //error:基類的保護成員在派生類中為保護成員,對對象不可見//a=objD.publicdateA; //error:基類的公共成員在派生類中為保護成員,對對象不可見return 0; }特別注意:
對于沒有申明權限類型的成員(包括函數和變量)
(1)如果是在struct內默認定義是public
(2)如果是class里面則是private
我在寫這段代碼的時候發現了另一個問題,具體就不在這里贅述了,一篇文章的內容不要太豐富,不然容易迷失方向,在之后的文章中分析~~~
就寫到這里~~~
—END—
參考文獻
[1]http://wenku.baidu.com/link?url=IS4T_0J4TY4-dFymmwnlP_kx5zGnBNFMQw5N9iF-pejvd1QPRcF-tmZ7G7JhEpdriNxaHo9P5Yv2ctKCTvJDz0tlHGlStatEHX5xOMCmDS7
總結
以上是生活随笔為你收集整理的关于C++中公有继承、私有继承、保护继承的讨论的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简述计算机数控系统的工作原理,计算机数控
- 下一篇: 小孔成像总结_【初中物理】物理解题技巧+